1. 程式人生 > 其它 >資料結構(3)—— 串

資料結構(3)—— 串

### 寫在前面

關於串,906的考綱內並沒有涉及,408中也只提到了模式匹配演算法(KMP演算法),因此這塊的內容會很少,並不會有太多涉及。

一如既往的,上一部分的地址:[資料結構(2)—— 棧與佇列](https://www.cnblogs.com/wushenjiang/p/15004139.html)。

### KMP匹配演算法

#### 注意點

需要注意的是,程式碼裡求next陣列的過程與我們手算的過程是不一樣的,因此這裡的思路僅做參考。

求next陣列的演算法流程,可以去看王道書和[KMP演算法(快速模式匹配演算法)詳解以及C語言實現 (biancheng.net)](http://data.biancheng.net/view/13.html)這個網址的講解,講的很不錯。以我的能力無法敘述很好,就在此藉助網路的力量了。

關於手算next陣列,可以參考王道2022考研的視訊,講解的很好。

這裡的程式碼使用了C++中定義好的string型別,並且把整體寫法偏向了C++風格(實際上也就是多了個namespace的宣告和列印方式的改變而已)。

#### 程式碼

```cpp
/*
 * @Description: KMP演算法實現
 * @version: 1.0
 * @Author: Liuge
 * @Date: 2021-07-13 21:20:30
 */

#include<bits/stdc++.h>
using namespace std;

// 求next陣列
// 這裡的字串是從0開始儲存的,所以需要下標-1
void getNext(string T,int next[]){
    int i=1;
    int j=0;
    next[1] = 0;
    while(i < T.length()){
        if(j == 0 || T[i-1] == T[j-1]){
            ++i;
            ++j;
            next[i] = j;
        }else{
            j = next[j];
        }
    }
}

// KMP演算法
int indexKMP(string S,string T,int next[]){
    int i=1;
    int j=1;
    while(i <= S.length() && j <= T.length()){
        if(j == 0 || S[i-1] == T[j-1]){
            ++i;
            ++j;
        }else{
            j = next[j];
        }
    }
    if(j > T.length()){
        return i - T.length();
    }else{
        return 0;
    }
}

// 主函式測試
int main(){
    string a = "ababcabcacbab";
    string b = "cabca";
    int next[100];
    getNext(b,next);
    cout << "子串b在子串a的起始位置為:" << indexKMP(a,b,next);
}

總結

這次實現並不是很難,而且由於考綱的要求比較低,且對程式碼也沒什麼要求,讀者湊合看看就好。按照王道書上所說,暴力迴圈來模式匹配的方式時間複雜度其實也沒那麼不堪,因此也被廣泛使用。在實際的專案中更多的是使用別人寫好的工具類,可以參考下真正的工程專案是如何實現模式匹配的。