每週一道算法淺析(尋找子字符串)

題:判斷一個字符串是否包含另一個字符串(尋找下標、尋找包涵幾個子串等)

看到問題首先想到循環一下就解決了,循環比對沒問題

bool test1(char *contentChars, char *itemChars) {
    bool searchSucc = false;
    int searchCount = 0;
    for (int i = 0; i < strlen(contentChars); i ++) {
        for (int j = i; j < strlen(contentChars); j ++) {
            if (contentChars[j] == itemChars[j]) {
                if (j >= strlen(itemChars)) {
                    searchCount ++;
                    searchSucc = true;
                    break;
                }
            } else {
                break;
            }
        }
    }
    
    return searchSucc;
}

這樣解題是可以解的,可以看到複雜度爲n*m,那有沒有別的解法可以優化一下。

所以引出了KMP算法,這裏不解釋KMP算法的原理(網上有很多解釋,可以去搜一下),直接上代碼

void buildNext(const char *T, int Next[]) {
    int i,j;
    Next[0] = -1;
    j = Next[1] = 0;
 
    for (i = 2; i < strlen(T); i++){
        while (j > 0 && T[i-1] != T[j]) j = Next[j];
        if (T[i-1] == T[j]) j++;
        Next[i] = j;
    }
}
bool stringContains(char *contentChars, char *itemChars) {
    unsigned long zLength = strlen(contentChars);
    unsigned long length = strlen(itemChars);
    
    int Next[128] = {0};
    buildNext(itemChars, Next);
    int i,j;
    i = j = 0;
    bool searchSucc = false;
    int searchCount = 0;
    int rollCount = 0;
    while (i < zLength) {
        rollCount ++;
        if (contentChars[i] == itemChars[j]) {
            i ++;
            j ++;
            if (j >= length) {
                searchSucc = true;
                searchCount ++;
                //找到,是否繼續尋找
                bool continueSearch = true;
                if (continueSearch) {
                    j = Next[j - 1] + 1;
                } else {
                    break;
                }
            }
        } else {
            i = i + (j == 0 ? 1 : 0);
            j = j > 0 ? Next[j] : 0;
        }
        
    }
    printf("尋找子字符串【%s】%s,共循環%d次,字符串長度%lu,共找到%d個",itemChars, searchSucc ? "成功" : "失敗", rollCount, zLength, searchCount);
    return searchSucc;
}

上面就是利用KMP算法進行查找子字符串

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章