如有一串字符"a b c d " 我想知道里面是否包含字符 c d 用传统的暴力算法 我们可以这样解:
java代码:
public static int char_next(char [] str, char str_s[])
{
int i=0; //主串下标
int j=0; //子串下标
while(str[i]<=str.length && str_s[j]<=str_s.length)
{
if(str[i+j]==str_s[j])
{
j++;
}
else
{
i++;
j=0;
}
}
return i-1;
}
当发生失配后, 也就是str[i+j]!=str_s[j]后那么子串发生失配了, 传统的算法就是让j(子串)回溯到开始位置
主串i+1 重新进行匹配。 这种算法虽然通熟易懂逻辑清晰但是效率堪忧。
下面给出我对KMP算法代码和理解,它是一种线性时间查找的算法,一开始接触时非常难懂。其实对于kmp算法,理解了它的next数组就差不多理解了怎个算法
kmp算法通过移动next数组在失配后重新进行匹配
import java.util.*;
public class kmp {
public static int [] getkmp_next(char str[])
{
int j=-1;
int k=0;
int next[]=new int [6];
next[0]=j;
while(k<=str.length-1)
if(j==-1 || str[j]==str[k])
{
j++;
k++;
next[k]=j; //存入next数组 j代表next值 k代表下标
}
else //当发生失配后重新开始匹配
j=next[j];
return next;
}
public static void main(String[]args)
{
char []str={'a','b','c','d'}; //主串
char []str_s={'c','d'}; //模式串
int p=str_s.length;
int r;
int next[]=getkmp_next(str_s); //求子串next值
int i=0; //主串下标
int j=-1; //子串下标
while(i<=str.length-1 &&j<=str_s.length-1)
if(j==-1 || str[i]==str_s[j])
{
i++;j++;
}
else //失配后j根据next的值决定子串移动位置
j=next[j];
if(j==p)
{
r=i-j;
System.out.println("从第"+r+"个位置开始匹配");
}
else
System.out.println("找不到匹配位置");
}
}
注释中是我对KMP算法的理解,若有不对之处还望各位大神轻喷。小弟一定改正。