1. 程式人生 > >程式設計之美讀書筆記3.1—字串移位包含的問題

程式設計之美讀書筆記3.1—字串移位包含的問題

給定兩個字串s1s2,要求判斷s2是否能夠被通過s1做迴圈移位(rotate)得到的字串包含。例如,S1=AABCDs2=CDAA,返回true;給定s1=ABCDs2=ACBD,返回false

1.      最直接的方法對S1進行迴圈移位,遍歷所有可能性。

#include <iostream>
using namespace std;
 
void main()
{
          char  s1[]="AABCD";
          char s2[]="CDAA";
 
          int len=strlen(s1);
          for (int i=0;i<len;i++)
          {
                    char temp=s1[0];
                    for (int j=0;j<len-1;j++)
                         s1[j]=s1[j+1];
                    s1[len-1]=temp;
 
                    if(strstr(s1,s2)!=NULL) //strstr() 函式搜尋一個字串在另一個字串中的第一次出現。找到所搜尋的字串,則該函式返回第一次匹配的字串的地址;如果未找到所搜尋的字串,則返回NULL。
                    {
                             cout<<"true";
                             break ;
                    }
         }
 }
 


2.     我們也可以對迴圈移位之後的結果進行分析。
以S1 = ABCD為例,先分析對S1進行迴圈移位之後的結果,如下所示:
ABCD--->BCDA---->CDAB---->DABC---->ABCD……
假設我們把前面的移走的資料進行保留,會發現有如下的規律:
ABCD--->ABCDA---->ABCDAB---->ABCDABC---->ABCDABCD……
因此,可以看出對S1做迴圈移位所得到的字串都將是字串S1S1的子字串。如果S2可以由S1迴圈移位得到,那麼S2一定在S1S1上,這樣時間複雜度就降低了。

#include <iostream>
#include <string>
using namespace std;
 
void main()
{
          string  s1="AABCD";
          string s2="CDAA";
                  
          s1=s1+s1;
          if(strstr(s1.c_str(),s2.c_str())!=NULL)
               cout<<"true";
 }