KMP算法模板

用自己的方法写出来了,下标很容易错。。。

其实感觉KMP算法还有改进的余地,因为 Pi[ ] 这个数组在计算的时候只会有两种情况:

1、要么碰到不等的数了,就为0

2、要么继续相等,就+1


#include <iostream>
#include <string.h>
using namespace std;

int Pi[100];  //最终的数组

/************************************************************************/
/* athor:Bill Wang                                                      */
/************************************************************************/


//计算每个子串的最大前缀pi
int count_max(char *P,int len)
{
	int i,j;
	//len是串长度
	for (i=len-1;i>=1;i--)
	{
		//从最乐观的开始,碰到一个可以的就返回
		for (j=1;j<=i;j++)
		{
			//这里只要匹配成功就可以返回了
			if (P[j] != P[len-i+j])
				break;
		}
		if(j>i)  //成功匹配
			return i;
	}
	return 0;
}



void Prefix_fun(char *P)
{
	//cout<<strlen(P)<<endl;
	int m=strlen(P);   //P的长度,这里是10
	Pi[1]=0;

	for(int q=2;q<=m;q++)
	{
		//已得到子串 如  abababa,计算其Pi
		Pi[q]=count_max(P,q);
	}

}



int main()
{
	char P[]="zababababca";

	Prefix_fun(P);

	for(int i=1;i<=10;i++)
		printf("%d ",Pi[i]);
	cout<<endl;

	while(1);

	return 0;
}


算导自带的算法:

#include <iostream>
#include <string.h>
using namespace std;

int Pi[100];  //最终的数组

void Prefix_fun(char *P)
{
	//cout<<strlen(P)<<endl;
	int m=strlen(P);   //P的长度,这里是10
	Pi[1]=0;
	int k=0;   //一个中间变量

	for(int q=2;q<=m;q++)
	{
		while( k>0 && P[k+1]!=P[q])
			k=Pi[k];

		if (P[k+1] == P[q])
			k++;

		Pi[q]=k;
	}

}



int main()
{
	char P[]="zababababca";

	Prefix_fun(P);

	for(int i=1;i<=10;i++)
		printf("%d ",Pi[i]);
	cout<<endl;

	while(1);

	return 0;
}






上一篇:笔试算法模拟题精解之“Bob的花束”


下一篇:asp.net使用post方式action到另一个页面,在另一个页面接受form表单的值!(报错,已解决!)