今天在朋友的推荐下去HPOJ刷了会算法题。感觉弱爆了,虽然题不难,但是写的代码都绕了一个弯子,没有大神们写的简单明了。还省内存。。今儿刷题的时候用了一下c语言,都忘得差不多了。。唉,平常都用java..
今儿就复习一下kmp算法吧,写给自己看的。
kmp是一个字符串匹配算法,保证了以最少次数比对。
KMP算法的核心是next数组,这个保证了最少次数的比对。
next[j]来记录失配时模式串应该用哪一个字符于Si进行比较。
private int[] Getnext(String s){
int[] next=new int[s.length()];
int k=-1;
int j=0;
next[0]=-1;
while(j<s.length()-1)
{
if (k==-1||s.charAt(k)==s.charAt(j))
{
next[++j]=++k;
}
else
{
k=next[k];
}
}
return next;
}
“a d s f w a s d f a s f a d s f a s d f”的next数组是
-1 0 0 0 0 0 1 0 0 0 1 0 0 1 2 3 4 1 0 0,if语句比较易懂,就是如果有重复的字符串的话就继续比对,else就是利用next数组的本质作用:失配时去和哪个字符去继续比对
现在就是利用next数组的时候了:
KMP(String S,String target){
int i=0;
int j=0;
int [] next=this.Getnext(target);
while(i<S.length()&&j<target.length())
{
if (j==-1||S.charAt(i)==target.charAt(j))
{
i++;
j++;
}
else
{
j=next[j];
}
}
if (j==target.length())
System.out.println(i-target.length()+"");
else
System.out.println("-1");
printf(this.Getnext(target));
}
看起来和求next很像啊,原理也差不多,next是自己比对自己,这个是比较母串。最后返回一个i-target.length()的意思是,如果上面的循环是在j已经等于子串的长度的时候,这种情况就是已经匹配成功了,i则记录匹配了多少次。减去其实子串长度次数的匹配就是除去验证性匹配的次数,换句话说就是模拟串匹配的情况,而不是一个一个字符匹配的情况,反正 我是懂了。。今儿就做这个算学习进度了吧~