串的定義:串(string)是由零個(gè)或多個(gè)字符組成的有限序列,又名叫字符串。零個(gè)字符的串稱為空串(null string)。
還有一些特別的字符串:
空格串:只包含空格的串。
子串與主串,串中任意個(gè)數(shù)的連續(xù)字符組成的子序列稱為該串的子串,相應(yīng)地,包含子串的串稱為主串。
串有兩種存儲結(jié)構(gòu),靜態(tài)和動(dòng)態(tài),靜態(tài)的存儲結(jié)構(gòu)一般使用一組地址連續(xù)的存儲單元來存儲,例如數(shù)組。使用數(shù)組,就需要在初始分配一個(gè)固定長度的存儲區(qū)域,這樣就有可能使:兩串的連接、新串的插入、以及字符串的替換的操作,超過數(shù)組的長度。為了解決這個(gè)問題,可以動(dòng)態(tài)分配串的存儲空間,使用鏈表結(jié)構(gòu)(一般情況下,對串的操作基本上是從頭到尾順序掃描,因此無需使用雙向鏈表)。
常用的串有7種基本操作:
1.賦值,2.判等(串的比較是通過比較字符的ASCII來進(jìn)行的),3.求長,4.鏈接,5.求字串,6.定位,7.置換
下面來說說在靜態(tài)存儲方式下,鏈接,求子串,求子串位置的操作
- 鏈接:
將S1與S2鏈接起來,成為S3,這時(shí)需要考慮,當(dāng)前S1的長度加當(dāng)前S2的長度沒有超過初始定義的最大數(shù)組長度,則S3=S1+S2,如果超過了,但是當(dāng)前S1的長度沒超最大值,則截?cái)郤2,如果S1當(dāng)前長度就超過最大值了,就截?cái)郤1。 - 求子串:
也是復(fù)制串的過程,將S中第start個(gè)字符開始,循環(huán)將len次,將字符復(fù)制進(jìn)sub串中。 - 求子串位置:
子串的定位操作通常稱為串的模式匹配。
設(shè)計(jì)思路如下:
a. 設(shè)i用于主串s1中當(dāng)前位置下標(biāo)值,j用于子串sub中當(dāng)前位置下標(biāo)值。
b. 首先比較s1[0]與sub[0],如果相同的話,可能子串就開始了。
c. 如果不相等,那么子串仍然是從sub[0]開始,而主串s1則以s1[1]與其比較。
d. 如果j==子串sub的長度,那么就找到子串了。
但是根據(jù)這種設(shè)計(jì),如果子串是00001,主串是0000000000001,這種情況下,每次都要比較到子串最后一位發(fā)現(xiàn)為1,才知道不相等,然后主串的指針又要回溯到i-4的位置,如果主串的0特別多,就要回溯很多次,所以出現(xiàn)了一種改進(jìn)的模式匹配:每當(dāng)一趟匹配過程中出現(xiàn)字符比較不等時(shí),不需回溯i指針,而是利用已經(jīng)得到的“部分匹配”的結(jié)果將模式向右“滑動(dòng)”盡可能遠(yuǎn)的一段距離后,繼續(xù)進(jìn)行比較。
舉個(gè)例子:
主串S:a b a b c a b c a c b a b,子串T:a b c m c
當(dāng)i=3,S[i]=b,當(dāng)j=3,T[j]=m,發(fā)現(xiàn)子串與主串不相等了,這時(shí)不用從i=1,j=0從頭開始比較,根據(jù)此輪比較發(fā)現(xiàn)主串與子串0-2的字符是相等的,而且0-2的字符也不是重復(fù)的,所以T[0]也就無需在和S[1],S[2]進(jìn)行比較了,i可以直接向右滑動(dòng)到3,繼續(xù)同T進(jìn)行比較,在整個(gè)匹配過程中,i的指針沒有回溯,減少了運(yùn)行時(shí)間。