* 有一个字符串 str = "be bed been bean better beach" 和一个子串 str0 = "bean"
* 判断 str 是否含有 str0,有则返回第一次出现的位置,没有返回-1
* 思路
* 循环主串每个字符 i 循环主串每个字符j
* 如果当前字符串匹配成功即str[i]==str[j],则i++,j++匹配下一个
* 如果匹配挫败 则将j置0,i =i-j+1,即匹配失败的后一个位置开始重新匹配
暴力匹配代码实现
/** * 字符串匹配 * 有一个字符串 str = "be bed been bean better beach" 和一个子串 str0 = "bean" * 判断 str 是否含有 str0,有则返回第一次出现的位置,没有返回-1 * 思路 * 循环主串每个字符 i 循环主串每个字符j * 如果当前字符串匹配成功即str[i]==str[j],则i++,j++匹配下一个 * 如果匹配挫败 则将j置0,i =i-j+1,即匹配失败的后一个位置开始重新匹配 * 效率低:每次只移动一位,匹配失败就移到下一位接着判断,浪费时间。 */ public class StringViolentMatchDemo { public static void main(String[] args) { String str = "be bed been bean bank better beach"; String str0 ="been"; char[] c = str.toCharArray(); char[] c0 =str0.toCharArray(); System.out.println(str+" "+c.length); System.out.println(str0+" "+c0.length); int i=0; int j=0; while (i<c.length&&j<c0.length){ if(c[i]==c0[j]){ i++; j++; } else{ i=i-j+1; j=0; } } if(j==c0.length){ System.out.println(i-j); } else{ System.out.println(-1); } } }
KMP匹配
利用之前判断过信息,通过next数组保存子串中前后最长共子序列的长度,每次回溯时,通过next数组找到,越过前面匹配过的位置,节省大量时间
部分匹配表的产生
代码实部分匹配值数组
private static int [] next(String str){ int [] arr = new int[str.length()]; arr[0]=0; for(int i=1,j=0;i<arr.length;i++){ int vi =str.charAt(i); int vj =str.charAt(j); char si =(char)vi; char sj =(char)vj; while (j>0&&vi!=vj){ j=arr[j-1]; } if(vi==vj){ j++; } arr[i]=j; } return arr; }
KMP利用部分匹配值实现字符串匹配
public static void main(String[] args) { //测试部分匹配值表 String strTest ="ABCDABD"; System.out.println(strTest+" 是否为 0 0 0 0 1 2 0 "); int [] next =next(strTest); System.out.println(Arrays.toString(next)); //测试KMP算法 String str = "be bed been bean bank better bean beach"; String str0 ="been"; int position = doKMPStringMatch(str,str0); System.out.println(str0+"在"+str+"中首次出来的位置为:"+position); } private static int doKMPStringMatch(String str,String s){ //计算部分匹配值 int [] next = next(s); System.out.println(s+" 的部分匹配值:"+Arrays.toString(next)); for (int i = 0,j=0; i < str.length(); i++) { int vi =str.charAt(i); int vj=s.charAt(j); while (j>0&&vi!=vj){ j=next[j-1]; } if(vi==vj){ j++; } if(j==s.length()){ return i-j+1; } } return -1; }