1. 程式人生 > >程式設計之美之字串移位包含問題

程式設計之美之字串移位包含問題

【題目】

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

【分析】

【思路一】

從題目中可以看出,我們可以使用最直接的方法對S1進行迴圈移動,再進行字串包含的判斷,從而遍歷其所有的可能性。

字串迴圈移動,時間複雜度為O(n),字串包含判斷,採用普通的方法,時間複雜度為O(n*m),總體複雜度為O(n*n*m)。

字串包含判斷,若採用KMP演算法,時間複雜度為O(n),這樣總體的複雜度為O(n*n)。若字串的長度n較大,顯然效率比較低。其中n為S1的長度,m為S2的長度。

【思路二】

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

【程式碼一】

/*********************************
*   日期:2014-5-15
*   作者:SJF0115
*   題號: 字串移位包含問題
*   來源:程式設計之美
**********************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

bool IsRotate(char* str1,char* str2){
    int i,j;
    if(str1 == NULL || str2 == NULL){
        return false;
    }
    int len = strlen(str1);
    //迴圈移位
    for(i = 0;i < len;i++){
        char temp = str1[0];
        //移動一位
        for(j = 1;j < len;j++){
            str1[j-1] = str1[j];
        }
        str1[len-1] = temp;
        //判斷str1中是否包含str2
        if(strstr(str1,str2) != 0){
            return true;
        }
    }
    return false;
}

int main(){
    char str1[6] = "AABCD";
    char str2[5] = "CDAA";
    bool result = IsRotate(str1,str2);
    cout<<result<<endl;
    return 0;
}

【程式碼二】

/*********************************
*   日期:2014-5-15
*   作者:SJF0115
*   題號: 字串移位包含問題
*   來源:程式設計之美
**********************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

bool IsRotate(char* str1,char* str2){
    int i,j;
    if(str1 == NULL || str2 == NULL){
        return false;
    }
    int len1 = strlen(str1);
    char* str3 = new char(len1*2+1);
    strcpy(str3,str1);
    strcat(str3,str1);
    //str3 = str1+str1
    if(strstr(str3,str2) != 0){
        return true;
    }
    return false;
}

int main(){
    char str1[6] = "AABCD";
    char str2[5] = "CDAA";
    bool result = IsRotate(str1,str2);
    cout<<result<<endl;
    return 0;
}