KMP算法实现的是数组字符串中的匹配问题:但是经典的数组匹配中,kmp算法只能实现256个字符的匹配,也就是说。最大的匹配字符串的长度是256。但是有很多时候我们需要找到的是在一个很长的字符串中找到我们需要的字符串,这就需要我们对这个算法进行改进。首先我们要看懂算法,算法中之所以有这样的限制是因为就字符串的串的长度这个变量保存到了字符数组的第一个字符中,这样长度就受到了限制。所以改进的方法是不用这个,而另外的传递一个参数替代原串的一个字符.
具体实现方法:
int next[256];
//寻找next的函数
void get_next(char T[],int *next)
{
int i=1,j=0;
next[1]=0;
while(i<=T[0])
{
if(j==0||T[i]==T[j])
{
++i;
++j;
next[i]=j;
}
else j=next[j];
}
}
//使用kmp算法的函数
int Index_KMP(char S[],char T[],int lenofT,int pos=0) //Index_KMP() function
{
int i=pos,j=1; //set Init_values
while(i<=lenofT&&j<=T[0]) //将lenofT 相当于算法中的S[0]
{
if (j==0||S[i]==T[j])
{
++i;
++j;
}
else
j=next[j];
}
if(j>T[0]) return (i-T[0]);
else return (0);
}
下面给出一个Demo程序:
#include<stdio.h>
#include<conio.h>
#include "string.h"
int next[256];
//寻找next的函数
void get_next(char T[],int *next)
{
int i=1,j=0;
next[1]=0;
while(i<=T[0])
{
if(j==0||T[i]==T[j])
{
++i;
++j;
next[i]=j;
}
else j=next[j];
}
}
//使用kmp算法的函数
int Index_KMP(char S[],char T[],int lenofT,int pos=0) //Index_KMP() function
{
int i=pos,j=1; //set Init_values
while(i<=lenofT&&j<=T[0]) //将lenofT 相当于算法中的S[0]
{
if (j==0||S[i]==T[j])
{
++i;
++j;
}
else
j=next[j];
}
if(j>T[0]) return (i-T[0]);
else return (0);
}
void main()
{
char c_Src[1024];
memset(c_Src,0,1024);
char S[1024];
memset(S,0,1024);
char T[11];
memset(T,0,11);
int m,n,r,k;
char c_url[256]; //存放取到的url字符串的数组
memset(c_url,0,256);
strcat(c_Src,"HTTP/1.1 302 Moved Temporarily");
strcat(c_Src,"/r/n");
strcat(c_Src,"Date: Fri, 25 May 2007 01:42:10 GMT");
strcat(c_Src,"/r/n");
strcat(c_Src,"Server: Apache/2.2.0 (Unix) PHP/5.1.2 mod_jk/1.2.19");
strcat(c_Src,"/r/n");
strcat(c_Src,"Location: http://9iwap.com/b2/index.jsp");
strcat(c_Src,"/r/n");
strcat(c_Src,"Content-Length: 0");
strcat(c_Src,"/r/n");
strcat(c_Src,"Keep-Alive: timeout=10, max=350");
strcat(c_Src,"/r/n");
strcat(c_Src,"Connection: Keep-Alive");
strcat(c_Src,"/r/n");
strcat(c_Src,"Content-Type: text/vnd.wap.wml;charset=UTF-8");
strcat(c_Src,"/r/n");
strcat(c_Src,"/r/n");
T[0]=10;
//实现从T[1]开始拷贝Location: 到T中的方法
//第一种方法:
//char *p_T="Location: ";
//for(int g=1;g<11;g++)
//{
//T[g]=*p_T;
// printf("%c",T[g]);
// *p_T++;
//}
//printf("/n");
//第二种:
memcpy(&T[1],"Location: ",10);
//strcpy(&T[1],"Location: ");
printf("the length of T:");
printf("%d/n",strlen(T));
//在T中多添加了一个/0
//求T的next:
get_next(T,next);
printf("the information header is:/n");
printf("******************************/n");
printf("%s",c_Src);
printf("******************************/n");
k=strlen(c_Src);//记录信息头的总的字节数
//S[0]=k;
printf("the size fo information header:");
printf("%d/n",k);
memcpy(&S[1],c_Src,k);
r=Index_KMP(S,T,k);
printf("the first character of Substring in Main String:");
printf("%d/n",r);
if(r=Index_KMP(S,T,k))
{
printf("The postion of T in the Main String S from /n");
printf("chars on is:%d/n",r);
}
else
printf("Failure to Index the String!/n");
//得到了Location: 开始的位置,这个字符串共有十个字符,那么就可以从这里开始一直往后取,直到/r/n
for(int i=0; ;i++)
{
if (c_Src[r+9+i]=='/r'&&c_Src[r+9+i+1]=='/n') {
break;
}
c_url[i]=c_Src[r+9+i];
}
printf("******************************/n");
printf("The destination url is:");
c_url[i]='/0';
printf("%s/n",c_url);
getch();
}