C 資料結構 字串

2021-08-21 02:43:59 字數 3692 閱讀 4516

(1)菜鳥教程——c++字串

(2)(3)

(4)官網教程:

(5)教程中的注釋:

(6)詳細的串定義與模式匹配演算法:

1、串的定義

串(字串的簡稱)是由零個或多個字元組成的有限序列,一般記為s='a1a2a3…an',其中ai可以是字母,數字或者其他字元,零個字元的串稱為空串

串中

任意個連續的字元組成的子串行

稱為該串的

子串,包含子串的串相應的被稱為主串,通常稱字元在序列中的序號為該字元在串中的位置。子串在主串中的位置則以子串的第乙個字元在主串中的位置來表示。兩個串相等,當且僅當這兩個串的值相等,即兩串的長度相等,且各個對應位置的字元也相等。

注意,空格串『 』與空串『』不一樣!!!為了清楚起見,書上用符號空集表示。

2、串的表示與實現

2.1 定長順序儲存表示

類似於線性表的順序儲存結構,串的順序儲存結構是用一組位址連續的儲存單元來儲存串中的字串行的。按照預定義的大小,為每個定義的串變數分配乙個固定長度的儲存區。

一般是用定長陣列來定義。

既然是定長陣列,就存在乙個預定義的最大串長度, 一般可以將實際的串長度值儲存在陣列的 0下標位置,有的書中也會定義儲存在陣列的最後乙個下標位置。但也有些程式語言不想這麼幹,覺得存個數字占個空間麻煩。

它規定在串值後面加乙個不計入串長度的結束標記字元,比如"\0"來表示串值的終結,這個時候,你要想知道此時的串長度,就需要遍歷計算一下才知道了,其實這還是需要占用乙個空間,確實沒必要。

串的順序儲存方式其實是有問題的,因為字串的操作,比如兩串的連線concat、新串的插入如insert,以及字串的替換 replace,都有可能使得串串行的長度超過了陣列的長度 maxsize。因此為克服這個弊病,唯有不限定串長的最大長度,即動態分配串值的儲存空間。

2.2 堆分配儲存表示

這種儲存表示的特點是,仍以一組位址連續的儲存單元存放串值字串行,但它們的儲存空間是在程式執行過程中動態分配而得。

2.3 串的塊鏈儲存表示

和線性表的鏈式儲存結構類似,也可以採用鍊錶方式儲存串值。由於串結構的特殊性——結構中每個資料元素是乙個字元,則採用鍊錶儲存串值,存在乙個「結點大小」的問題,即每個結點可以存放乙個字元,也可以存放多個字元。因此,乙個結點可以存放乙個字元,也可以考慮存放多個字元,最後乙個結點若是未被佔滿時,可以用"#"或其他非串值字元補全。

3、串的模式匹配演算法

3.1 求子串位置的定位函式 index(s,t,pos)

子串的定位操作通常稱做串的模式匹配(t稱為模式串,s稱為主串)。

其基本思想為:從主串s的第pos個字元起和模式串t中的第乙個字元比較,若相等,則繼續逐個比較後續字元;否則從主串的下乙個字元起再重新和模式串t中的字元比較。依次類推,直至模式串t中的每個字元依次和主串s中的乙個連續的字串行相等,則稱為匹配成功函式值為和模式串t中第乙個字元相等的字元在主串s中的序號,否則稱匹配不成功,函式值為0。該方法的時間複雜度為:o(n*m),但在實際情況下,其執行時間約為o(n+m),因此至今仍被採用。其具體函式為:

int index(string s, string t, int pos)

else

} if (j > t[0])

return i - t[0];

else

return 0;

}//index

3.2 kmp演算法kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱kmp演算法)。kmp演算法的關鍵是利用匹配失敗後的資訊(已經匹配的部分中的對稱資訊),儘量減少模式串(待搜尋詞)與文字串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next()函式,該函式本身包含了模式串的區域性匹配資訊。其時間複雜度為o(n+m)。詳細關於kmp演算法的介紹見:

為了便於理解這個next函式,舉個簡單的例子(牛客網字串必考題)說明一下:

題目:在kmp演算法中,已知模式串為adabcadada,請寫出模式串的next陣列值?(a)

a. 0,1,1,2,1,1,2,3,4,3

b. 0,1,1,1,2,1,2,3,4,3

c. 2,1,1,2,1,1,2,3,3,4

d. 1,2,3,2,1,1,2,4,4,3

next陣列值的解法:

(1)求模式串中,字首字尾最大的相同長度

a  d  a  b  c  a  d  a  d  a

0   0  1  0  0  1   2   3  2  3

(2)將字首陣列後移一位,並將第一位,置-1

-1  0  0  1  0  0  1   2  3  2

(3)將移位後的陣列整體+1

0  1  1  2  1  1   2  3  4  3

nextval陣列值的解法(或者參考**:解法):

(1)在計算出next值得同時,如果a位字元與它next值指向的b位字元相等,則該a位的nextval就是指向b位的nextval值;

(2)如果不等,則該a位的nextval值就是它自己a位的next的值。

上面的nextval陣列值為:

序號:                1    2   3   4   5   6   7   8   9  10

字串:            a   d   a  b  c   a  d   a  d   a

next陣列值:     0   1    1   2   1   1   2   3   4   3

nextval陣列值:0   1    0   2    1   0  1   0   4    0

c++**為:

#include #include using namespace std;

inline void next(const string &t, vector&next)

}inline string::size_type count_kmp(const string &s, const string &t)

//反向查詢子串在str中最後出現的位置

string flag = "to";

position = str.rfind(flag);

cout << "str.rfind(flag):" << position << endl;

getchar();

return 0;

}

執行結果:

資料結構 字串

1 字串 include string.h include stdio.h include stdlib.h include math.h include time.h define ok 1 define error 0 define true 1 define false 0 define ma...

資料結構 字串

字串是由0個或多個字元構成的序列,可記為s a1a2a3 an 其中ai可以是字母,也可是數字或者其他字元,零個字元的串稱為空串。而字串的順序結構就是用簡單的char型別陣列來儲存沒什麼好說的,下面介紹一下bf演算法與kmp演算法 bf演算法就是比較平常的雙重迴圈,如果匹配成功打斷迴圈,否則子串的比...

資料結構 字串

靜態陣列實現 順序儲存 串的順序儲存 define maxlen 255 預定義最大串長為255 typedef struct 靜態陣列實現 順序儲存 sstring 動態陣列實現 堆分配儲存 typedef struct 動態陣列實現 堆分配儲存 hstring 初始化void inithstri...