C語言不支援真正意義上的字元串,使用字元指針和字元數組實作字元串存儲,使用C庫函數實作字元串操作。
C++為了相容C語言,也不支援原生的字元串類型,但可以通過自定義類類型完成字元串類型的定義。
繼承自頂層父類Object,内部封裝C語言中的字元串操作。
1.無縫實作String對象和char*字元串的互操作;
2.操作符重載函數需要考慮是否支援const版本
3.通過C語言中的字元串函數實作String的成員函數
DTstring聲明:
字元串類中的常用成員函數:
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;
3.在指定位置插入字元串
String& insert(int i, const char* s);
String& insert(int i, const String& s);
4.去掉字元串兩端的空白字元串
String& trim();
思考:如何在目标字元串中查找是否存在指定的子串?
問題:如何在目标字元串中查找是否存在指定的子串?
先比對子串和目标字元串的第一個字元,如果比對則繼續比對第二個字元...
如果比對失敗,則從目标字元串的第二個字元與子串進行比對, ...
通過兩個嵌套的for循環完成,最終的時間複雜度為O(n^2)。
樸素解法的一個優化方向:
因為, Pa != Pb,且Pb = Sb;是以Pa != Sb,結論,子串p右移1位比較沒有意義。
偉大的發現:
1.比對失敗時的右移位數與子串本身相關,與目标串無關;
2.移動位數 = 已知比對的字元數 - 對應的部分比對值
3.任意一個子串都存在一個唯一的部分比對表。
那麼部分比對表是如何得到的呢?
字首:除了最後一個字元外,一個字元串的全部頭部組合;
字尾:除了最後一個字元外,一個字元串的全部尾部組合;
部分比對值:字首和字尾最長共有元素的長度。
下面以ABCDABD為例:
上面我們使用求字首和字尾交集最大長度的方法得到了部分比對值,但如何通過程式設計來産生部分比對表呢?
實作關鍵:
1.PMT[1] = 0(下标為1的字元開始遞推)
2.從第二個字元開始遞推(從下标為1的字元開始遞推)
3.假設PMT[n] = PMT[n-1]+1(最長共有元素的長度)
4.當假設不成立,PMT[n]在PMT[n-1]的基礎上減小,直至為0
總結:
1.部分比對表是提高子串查找效率的關鍵,可以使用遞推的方式産生部分比對表;
2.部分比對值定義為字首和字尾最長共有元素的長度;
3.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, ...