我們經常需要儲存和處理字元資訊,因此就有了「串」這個資料結構。
串( string )是由零個或多個字元組成的有限序列,又名叫字串。串一般記為s=
「a1a
2...
...a
n」s =「
a1a2
....
..an
」s 是串的名稱。串中的字元數目 n 稱
為串的長度,當n為0是稱為空串。
空格串只包含空格的串,空格串不是空串,它可以包含多個空格。
子串與主串串中任意個數的連續字元組成的子串行稱為該串的子串,相應地,包含子串的串稱為主串。
串的比較
數值很容易進行比較,那麼字串如何進行比較呢?
對於給定的兩個串s=
「a1a
2...
...a
n」s =「
a1a2
....
..an
」,t=
「b1b
2...
...b
n」t =「
b1b2
....
..bn
」當滿足以下條件之一時,
s<
t s
n<
m n
<
m,且a
i=bi
(i=1
,2,3
,...
...,n)a
i=bi
(i=1
,2,3
,...
...,
n)。存在某個k⩽
min(
m,n)k⩽
min(
m,n)
,使得ai=
bi(i
=1,2
,3,.
....
.,k),ak
ai=b
i(i=
1,2,
3,..
....
,k),
ak串的順序儲存結構
串的順序儲存結構我們用陣列來實現,為了更好判斷串的截止,我們一般用「\0」表示串值的終結。還有一種方法是將串的長度儲存在陣列的0下標的位置。
串的鏈式儲存結構
串的鏈式儲存結構,與線性表是相似的。只不過串鍊錶結點中的資料元素儲存的是乙個或多個字元。當結點中的資料元素未被佔滿時可以用「#」或其他非率值字元補全。總體來說,串的鏈式儲存結構不如串的順序儲存結構來的實用。
串的模式匹配與kmp演算法
在串的操作中我們經常需要查詢子串在主串中的位置,比如查詢乙個詞在一篇文章中的位置等,像這樣子串的定位操作通常稱做串的模式匹配。最簡單的做法就是暴力匹配,就是重第乙個位置開始進行匹配,匹配不成功就移動到主串第二個位置進行匹配。這樣做對於兩個長度分別為n和m串的模式匹配的時間複雜度就為o(
n∗m)
o (n
∗m)。能不能有更好的匹配方案呢?
我們先來舉個栗子,主串s="
abcd
eacd
fe" s="a
bcde
acdf
e",待匹配串t="
abcd
x"t ="a
bcdx
"。我們看到兩個字串的前四個字元相同,第5個字元不同,且前四個字元各不相同,所以我們第二次匹配可以從主串的第5個字元開始,因為t中「a」與」b」「c」「d」不同而子串與主串前四位字元又相同,所以t從s的第二到第四的位置開始也不能與主串匹配。這樣就省去了不少的匹配過程,提高了效率。
那麼如何又如何讓計算機知道下次從**開始匹配呢?這裡我們介紹乙個模式匹配演算法,克努特一莫里斯一普拉特演算法, 簡稱kmp 演算法。kmp 演算法通過t 串各個位置的 j 值的變化定義為乙個陣列 next來確定下個匹配位置。next陣列只和代匹配串t有關,與主串無關,其定義如下:ne
xt[j
]=⎧⎩
⎨⎪⎪⎪
⎪−1,
當j=0
時max
0,其他
情況n ex
t[j]
=0,其
他情況陣列 next建立**如下:
void get_next(string t,int * next)
else
}cout << endl;
}kmp具體**如下:
#include
#include
using
namespace
std;
void get_next(string t, int * next);
int kmp(string s, string t);
int main()
system("pause");
return0;}
void get_next(string t,int * next)
else
}}int kmp(string s, string t)
else
}delete next;
if (j ==(int) t.length())
else
}在vs上執行結果如下:
資料結構6 串
串是一種特殊的線性表,串中每個資料元素都是乙個單字元,對串進行操作時,經常將若干字元作為乙個整體進行處理。s是串名,引號不屬於串的內容。串賦值strassign sqstring s1,sqstring s2 求串長strlength sqstring s 串比較strcompare sqstrin...
資料結構與演算法分析 c 版 6 雙鏈表
雙鏈表 下面是雙鏈表的結點類實現 template class node node node preval nullptr,node nextval nullptr 過載操作符 void operator new size t void operator delete void template n...
讀《資料結構(C語言版)》(6)
本來上一節介紹鏈式表示時,還應提到迴圈鍊錶和雙向鍊錶,但我決定還是不提為好。如果將學習一門課程的方法比作遍歷演算法的話,我覺得廣度優先演算法要比深度優先演算法好。一門全新的課程,如果一開始就進入具體的細節的話,很容易有挫折感,進而喪失興趣。所以如果能對這門課程有乙個大局觀,了解這門課程是講什麼的,涉...