天天看點

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

C語言不支援真正意義上的字元串,使用字元指針和字元數組實作字元串存儲,使用C庫函數實作字元串操作。

C++為了相容C語言,也不支援原生的字元串類型,但可以通過自定義類類型完成字元串類型的定義。

繼承自頂層父類Object,内部封裝C語言中的字元串操作。

1.無縫實作String對象和char*字元串的互操作;

2.操作符重載函數需要考慮是否支援const版本

3.通過C語言中的字元串函數實作String的成員函數

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

DTstring聲明:

字元串類中的常用成員函數:

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

1.重載數組通路操作符[]

char& operator [] (int i);

char& operator [] (int i) const;

注意事項:

當i值取值不合法時,抛出異常。合法範圍(0<=i) && (i<m_length)

2.判定是否以指定字元串開始或結束

bool startWith(const char s) const;

bool startWith(const String& s) const;

bool endOf(const char s) const;

bool endOf(const String& s) const;

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

3.在指定位置插入字元串

String& insert(int i, const char* s);

String& insert(int i, const String& s);

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

4.去掉字元串兩端的空白字元串

String& trim();

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

思考:如何在目标字元串中查找是否存在指定的子串?

問題:如何在目标字元串中查找是否存在指定的子串?

先比對子串和目标字元串的第一個字元,如果比對則繼續比對第二個字元...

如果比對失敗,則從目标字元串的第二個字元與子串進行比對, ...

通過兩個嵌套的for循環完成,最終的時間複雜度為O(n^2)。

樸素解法的一個優化方向:

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

因為, Pa != Pb,且Pb = Sb;是以Pa != Sb,結論,子串p右移1位比較沒有意義。

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

偉大的發現:

1.比對失敗時的右移位數與子串本身相關,與目标串無關;

2.移動位數 = 已知比對的字元數 - 對應的部分比對值

3.任意一個子串都存在一個唯一的部分比對表。

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

那麼部分比對表是如何得到的呢?

字首:除了最後一個字元外,一個字元串的全部頭部組合;

字尾:除了最後一個字元外,一個字元串的全部尾部組合;

部分比對值:字首和字尾最長共有元素的長度。

下面以ABCDABD為例:

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

上面我們使用求字首和字尾交集最大長度的方法得到了部分比對值,但如何通過程式設計來産生部分比對表呢?

實作關鍵:

1.PMT[1] = 0(下标為1的字元開始遞推)

2.從第二個字元開始遞推(從下标為1的字元開始遞推)

3.假設PMT[n] = PMT[n-1]+1(最長共有元素的長度)

4.當假設不成立,PMT[n]在PMT[n-1]的基礎上減小,直至為0

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

總結:

1.部分比對表是提高子串查找效率的關鍵,可以使用遞推的方式産生部分比對表;

2.部分比對值定義為字首和字尾最長共有元素的長度;

3.KMP利用部分比對值與子串移動位數的關系提高查找效率。

資料結構(09)_字元串類的實作1.字元串類的建立(上)2.字元串類的建立(下)3.KMP子串查找算法4.KMP算法的應用

1.子串查找(kmp算法的直接應用)

2.在字元串中将指定的字元串删除

根據kmp在目标字元串中查找子串的位置,通過子串位置和長度進行删除。

3.字元串的減法操作定義(opeator -)

使用remove實作字元串間的減法操作,注意:字元串本身不被修改,傳回産生的新串。

4.字元串中的子串替換

Eg:在字元串”abcdefg”中将”cd”替換為”xyz” ?

1.使用kmp/indexOf擷取cd所在的位置

2.使用remove()删除字元串“cd”;

3.将字元串”xyz”,使用insert插入1中擷取的位置。

5.從字元串建立子串

以i為起點提取長度為len的子串,子串提取不會改變原來字元串的狀态。

方法:從字元串的i位置開始拷貝長度為len的子串出來

<code>String sub(int i, int len) const</code>

字元串類是工程開發中必不可少的元件,應當包含常用的增删查改操作;

增 : insert, operator +, ...

删 : remove, operator -, ...

查 : indexOf, ...

改 : replace, ...