兩串旋轉問題(KMP)

若是對於一個字符串A,將A的前面任意一部分挪到後邊去造成的字符串稱爲A的旋轉詞。好比A="12345",A的旋轉詞有"12345","23451","34512","45123"和"51234"。對於兩個字符串A和B,請判斷A和B是否互爲旋轉詞。ios

給定兩個字符串AB及他們的長度lenalenb,請返回一個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 }
相關文章
相關標籤/搜索