题目描述
给定一个主串S和子串P,使用KMP算法查找子串P在主串S中存在的位置,若子串P在主串S中存在,则输出与子串P中第一字符相等的字符在主串S中的序号;若不存在则输出“no”
程序输入格式:主串S 子串P;
程序输出格式:输出与子串P中第一字符相等的字符在主串S中的序号;
输入样例:ababcabcacbab abcac
输出样例:5
附件
样例输入输出
样例1
输入:
ababcabcacbab abcac
输出:
5
样例2
输入:
ABCDABCDABDE DBAEA
输出:
no
#include <iostream>
#include <string>
using namespace std;
void getnext(string t,int next[])
{
next[1]=0;
int i=1,j=0;
while (i<t.length()-1)
{
if (j==0||t[i]==t[j])
{
++i;++j;
next[i]=j;
}
else
j=next[j];
}
//优化版
for (int m=2;m<t.length();m++)
{
if (t[m]==t[next[m]])
{
next[m]=next[next[m]];
}
}
}
void Index_KMP(string s,string t)
{
int *next=new int[t.length()+1];
getnext(t,next);
/*for (int i = 1; i < t.length(); i++)
{
cout<<next[i]<<" ";
}
cout<<endl;
*/
int i=1;int j=1;
while (i<s.length()&&j<t.length())
{
if (j==0||s[i]==t[j])
{
++i;++j;
}
else
{
j=next[j];
}
}
if (j>=t.length())
{
cout<< i-t.length();
delete []next;
}
else
{
cout<<"no";
delete []next;
}
}
int main()
{
string s,t;
cin>>s;
cin>>t;
Index_KMP(" "+s," "+t);
system("pause");
return 0;
}
对于这道题有一种next是从-1开始的
但是会出现问题
//这里出现-1大于 .length() or .size() 的情况是因为-1变成无符号是补码全为1超级大
//因为string的size类型是size_t,一般是32位或者64位无符号整数;而-1是int类型,
//在与unsigned int(也可能是unsigned long等等,看你具体编译器)进行比较时会被提升为相应的无符号类型,而-1的二进制补码是全1,
//把全1的二进制码当做无符号数解释的时候是无符号数的最大值,所以-1是最大的。
所以要把t.length() 变成 signed(t.length())再和-1比较
#include <string>
using namespace std;
void getnext(string t,int next[])
{
next[0]=-1;
int i=0,j=-1;
while(i<t.length()-1)
{
if (j==-1||t[i]==t[j])
{
++i;++j;
next[i]=j;
}
else
{
j=next[j];
}
}
//这个优化可有可无
for (int m=2;m<t.length();m++)
{
if (t[m]==t[next[m]])
{
next[m]=next[next[m]];
}
}
}
void kmp(string s,string t)
{
int *next=new int[t.length()];
getnext(t,next);
int i=0,j=0;
//这里出现-1大于 .length() or .size() 的情况是因为-1变成无符号是补码全为1超级大
//因为string的size类型是size_t,一般是32位或者64位无符号整数;而-1是int类型,
//在与unsigned int(也可能是unsigned long等等,看你具体编译器)进行比较时会被提升为相应的无符号类型,而-1的二进制补码是全1,
//把全1的二进制码当做无符号数解释的时候是无符号数的最大值,所以-1是最大的。
while (i<s.length()&&j<signed(t.length()))
{
if (j==-1||s[i]==t[j])
{
++i;++j;
}
else
{
j=next[j];
}
}
if (j>=signed(t.length()))
{
cout<< i-t.length();
delete []next;
}
else
{
cout<<"no";
delete []next;
}
}
int main()
{
string s,t;
cin>>s;
cin>>t;
kmp(s,t);
system("pause");
return 0;
}