两串旋转问题(KMP)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两串旋转问题(KMP)相关的知识,希望对你有一定的参考价值。
如果对于一个字符串A,将A的前面任意一部分挪到后边去形成的字符串称为A的旋转词。比如A="12345",A的旋转词有"12345","23451","34512","45123"和"51234"。对于两个字符串A和B,请判断A和B是否互为旋转词。
给定两个字符串A和B及他们的长度lena,lenb,请返回一个bool值,代表他们是否互为旋转词。
测试样例:
"cdab",4,"abcd",4
返回:true
题目解析:针对测试用例来说,利用KMP判断“cdabcdab"中是否含有子串"abcd",因为任意串自身连接包含所有旋转可能。
一般KMP的C++实现如下:
1 #include<iostream> 2 #include<string.h> 3 using namespace std; 4 char str1[80]; 5 char str2[80]; 6 int next[80]; 7 8 9 void GetNext(char* p,int next[]){ 10 int pLen = strlen(p); 11 next[0] = -1; 12 int k = -1; 13 int j = 0; 14 while (j < pLen - 1){ 15 //p[k]表示前缀,p[j]表示后缀 16 if (k == -1 || p[j] == p[k]){ 17 ++k; 18 ++j; 19 next[j] = k; 20 } 21 else k = next[k]; 22 } 23 } 24 25 int KMP(char *pattern,char *str){//判断是否存在子串 26 int i,j; 27 int plen=strlen(pattern); 28 int len=strlen(str); 29 for(i=0;i<len;){ 30 for(j=0;j<plen;j++){ 31 if(str[i+j]!=pattern[j]) 32 break; 33 } 34 if(j==plen) 35 return 1; 36 i+=j-next[j]; 37 } 38 return 0; 39 } 40 41 int main(){ 42 cin.getline(str1,80); 43 cin.getline(str2,80); 44 GetNext(str2,next); 45 if(KMP(str2,str1)){ 46 cout<<"匹配成功!"; 47 } 48 return 0; 49 }
C++中string有+算符重载的连接功能。按题意修改算法原型,得到初步结果如下(输入输出格式未调整):
输入:cdab
abcd
输出:true
1 #include<iostream> 2 #include<string.h> 3 using namespace std; 4 int next[80]; 5 6 7 void GetNext(string p,int next[]){ 8 int pLen = p.length(); 9 next[0] = -1; 10 int k = -1; 11 int j = 0; 12 while (j < pLen - 1){ 13 //p[k]表示前缀,p[j]表示后缀 14 if (k == -1 || p[j] == p[k]){ 15 ++k; 16 ++j; 17 next[j] = k; 18 } 19 else k = next[k]; 20 } 21 } 22 23 int KMP(string pattern,string str){//判断是否存在子串 24 int i,j; 25 int plen=pattern.length(); 26 int len=str.length(); 27 for(i=0;i<len;){ 28 for(j=0;j<plen;j++){ 29 if(str[i+j]!=pattern[j]) 30 break; 31 } 32 if(j==plen) 33 return 1; 34 i+=j-next[j]; 35 } 36 return 0; 37 } 38 39 int main(){ 40 string str1,str2; 41 cin>>str1; 42 cin>>str2; 43 if(str1.length()!=str2.length()||str1.length()==0||str2.length() ==0){ 44 cout<<"false"; 45 }else{ 46 str1+=str1; 47 GetNext(str2,next); 48 if(KMP(str2,str1)){ 49 cout<<"true"; 50 } 51 } 52 return 0; 53 }
以上是关于两串旋转问题(KMP)的主要内容,如果未能解决你的问题,请参考以下文章