Dijkstra算法
传说中的KMP
字符串匹配的Θ(n)算法。
伪代码:
KMP(t,p)
{
n=length(t);//原子串
m=length(p);//待匹配子串
pi=cpf(p);一个初始化,下面会有解释。
q=0;
for(i=1;i<=n;i++)
{
while(q>0&&p[q+1]!=t[i])q=pi[q];//如果不匹配,移动!
if([p+1]==t[i])q++;如果匹配那就下一个
if(q==m)q=pi[q];//完成匹配了吗??then进行下一轮匹配
}
}
cpf(int p)
{
m=length(p);
pi[1]=0;//它不需要前缀;
k=0;
for(q=2;q<=m;q++)
{
while(k>0&&p[k+1]!=p[q])k=pi[k];//还是移动哈。
if(p[k+1]=p[q])k++;//匹配那么k++;
pi[q]=k;//此时如果再次移动的话,就要把头从q移动到k了。
}
关键问题就是那个闹心的前缀Prefix函数!
解释下
对于A aabaaaaab
和 B aaaaab
因为a[3]=b
那么在移动的时候b[1]一定不能和a[3]匹配,同理a[1],a[2]都是浪费时间的匹配,哪么prefix函数就要计算它到底要移动多少
如果一个字串的子串a[i...j] a[i’...j’]满足a[i]=a[i’]……a[j]=a[j’]那么就可以从i位置直接移动到J位置并且继续计算!(当前匹配了j-i+1个,怎么算的不要问我!)
然后在Matrix67牛的blog里发现了这个
KMP主程序:
字符串匹配的Θ(n)算法。
伪代码:
KMP(t,p)
{
n=length(t);//原子串
m=length(p);//待匹配子串
pi=cpf(p);一个初始化,下面会有解释。
q=0;
for(i=1;i<=n;i++)
{
while(q>0&&p[q+1]!=t[i])q=pi[q];//如果不匹配,移动!
if([p+1]==t[i])q++;如果匹配那就下一个
if(q==m)q=pi[q];//完成匹配了吗??then进行下一轮匹配
}
}
cpf(int p)
{
m=length(p);
pi[1]=0;//它不需要前缀;
k=0;
for(q=2;q<=m;q++)
{
while(k>0&&p[k+1]!=p[q])k=pi[k];//还是移动哈。
if(p[k+1]=p[q])k++;//匹配那么k++;
pi[q]=k;//此时如果再次移动的话,就要把头从q移动到k了。
}
关键问题就是那个闹心的前缀Prefix函数!
解释下
对于A aabaaaaab
和 B aaaaab
因为a[3]=b
那么在移动的时候b[1]一定不能和a[3]匹配,同理a[1],a[2]都是浪费时间的匹配,哪么prefix函数就要计算它到底要移动多少
如果一个字串的子串a[i...j] a[i’...j’]满足a[i]=a[i’]……a[j]=a[j’]那么就可以从i位置直接移动到J位置并且继续计算!(当前匹配了j-i+1个,怎么算的不要问我!)
然后在Matrix67牛的blog里发现了这个
KMP主程序:
Code
道理是一样的,应该是算法导论的翻译版,那句Pattern occurs with shift都没变^_^。给学Pascal的缺参考吧。