题目:
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2594
题意:
给你两个字符串s1和s2,计算s1的前缀和s2的后缀匹配的最大长度。
算法:
KMP字符串匹配算法。KMP匹配算法,返回值是匹配串在模式串中的下标,代码如下:
int KMP(const char *s1,const char *s2) //const 表示函数内部不会改变这个参数的值。
{
if(!s1 || !s2 || s2[0]=='\0' || s1[0]=='\0')
return -1;//空指针或空串,返回-1。
int len = 0;
const char *c = s2;
while(*c++ != '\0')//移动指针比移动下标快。
{
++len;//字符串长度。
}
int *next = new int[len+1];
get_nextval(s2,next);//求s2的next函数值
int index = 0,i = 0,j = 0;
while(s1[i]!='\0' && s2[j]!='\0')
{
if(s1[i] == s2[j])
{
++i;// 继续比较后继字符
++j;
}
else
{
index += j-next[j];
if(next[j] != -1)
j = next[j];// 模式串向右移动
else
{
j = 0;
++i;
}
}
}
delete []next;
if(s2[j] == '\0')
return index;// 匹配成功
else
return -1;
}
思路:
用s2的next数组计算。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s1[100010],s2[50005];
int len1,len2,next[100010];
void get_nextval(char s2[],int len)
{
int i,j;
i = -1;
j = 0;
next[0] = -1;
while(j<len)
{
if(i == -1 || s2[i] == s2[j])
{
j++; i++;
next[j] = i;
}
else
i = next[i];
}
}
int KMP(int len1,int len2)
{
int i,j;
i = 0;
j = 0;
while(i < len2)//计算s1和s2前后缀的匹配长度(注意j=0的情况)
{
if(j == -1 || s1[j] == s2[i])
{
i++;j++;
}
else
j = next[j];
}
if(j == 0)
{
if(s1[0] == s2[len2 - 1])
return 1;
else
return 0;
}
else
return j;
}
int main()
{
//freopen("input.txt","r",stdin);
int num;
while(gets(s1))
{
gets(s2);
len1 = strlen(s1);
len2 = strlen(s2);
get_nextval(s1,len1);
num = KMP(len1,len2);
if(num == 0)
printf("0\n");
else
{
for(int i=0; i<num; i++)
printf("%c",s1[i]);
printf(" %d\n",num);
}
}
return 0;
}
我原来的做法是用strcat()函数;wa啦。。考虑不周啊。。。好悲伤。。。。。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s1[100010],s2[50005];
int len,next[100010];
void get_nextval(char s2[],int len)
{
int i,j;
i = -1;
j = 0;
next[0] = -1;
while(j<len)
{
if(i == -1 || s2[i] == s2[j])
{
j++; i++;
next[j] = i;
}
else
i = next[i];
}
}
int main()
{
//freopen("input.txt","r",stdin);
while(gets(s1))
{
gets(s2);
strcat(s1,s2);
len = strlen(s1);
get_nextval(s1,len);
for(int i=0; i<next[len]; i++)
printf("%c",s1[i]);
if(next[len] == 0)
printf("0\n");
else
printf(" %d\n",next[len]);
}
return 0;
}