課件和試卷數(shù)據(jù)結(jié)構(gòu)第四章串_第1頁
課件和試卷數(shù)據(jù)結(jié)構(gòu)第四章串_第2頁
課件和試卷數(shù)據(jù)結(jié)構(gòu)第四章串_第3頁
課件和試卷數(shù)據(jù)結(jié)構(gòu)第四章串_第4頁
課件和試卷數(shù)據(jù)結(jié)構(gòu)第四章串_第5頁
已閱讀5頁,還剩51頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第四章串4.1串的抽象數(shù)據(jù)類型的定義4.2串的表示和實(shí)現(xiàn)4.3 串的模式匹配算法4.1串的抽象數(shù)據(jù)類型的定義如下:ADTString{

數(shù)據(jù)對象:D={ai|ai∈CharacterSet,i=1,2,...,n,n≥0}數(shù)據(jù)關(guān)系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,...,n}串是有限長的字符序列,由一對單引號相括,如:astring

基本操作:

StrAssign(&T,chars)

StrCopy(&T,S)

StrEmpty(S)

StrCompare(S,T)

StrLength(S)

Concat(&T,S1,S2)SubString(&Sub,S,pos,len)

Index(S,T,pos)

Replace(&S,T,V)StrInsert(&S,pos,T)StrDelete(&S,pos,len)

ClearString(&S)}ADTString

StrAssign(&T,chars)

初始條件:chars是字符串常量。

操作結(jié)果:把chars賦為T的值。

StrCopy(&T,S)

初始條件:串S存在。

操作結(jié)果:由串S復(fù)制得串T。

StrEmpty(S)

初始條件:串S存在。

操作結(jié)果:若S為空串,則返回TRUE,

否則返回FALSE。

表示空串,空串的長度為零。

StrCompare(S,T)

初始條件:串S和T存在。

操作結(jié)果:若ST,則返回值

0;

若ST,則返回值

0;

若ST,則返回值

0。例如:StrCompare(data,state)<0StrCompare(cat,case)>0

StrLength(S)

初始條件:串S存在。

操作結(jié)果:返回S的元素個(gè)數(shù),

稱為串的長度。

Concat(&T,S1,S2)

初始條件:串S1和S2存在。

操作結(jié)果:用T返回由S1和S2

聯(lián)接而成的新串。例如:

Concate(T,man,kind)

求得T=mankind

SubString(&Sub,S,pos,len)初始條件:

串S存在,1≤pos≤StrLength(S)

且0≤len≤StrLength(S)-pos+1。操作結(jié)果:

用Sub返回串S的第pos個(gè)字符起長度為len的子串。例如:

SubString(sub,commander,4,3)

求得sub=man;

SubString(sub,commander,1,9)求得sub=commander;

SubString(sub,commander,9,1)求得sub=r;子串為“串”中的一個(gè)字符子序列SubString(sub,commander,4,7)sub=?SubString(sub,beijing,7,2)=?sub=?SubString(student,5,0)=起始位置和子串長度之間存在約束關(guān)系長度為0的子串為“合法”串

Index(S,T,pos)

初始條件:串S和T存在,T是非空串,

1≤pos≤StrLength(S)。

操作結(jié)果:

若主串S中存在和串T值相同

的子串,則返回它在主串S中第pos個(gè)

字符之后第一次出現(xiàn)的位置;

否則函數(shù)值為0。

假設(shè)S=abcaabcaaabc,T=bca

Index(S,T,1)=2;Index(S,T,3)=6;Index(S,T,8)=0;“子串在主串中的位置”意指子串中的第一個(gè)字符在主串中的位序。

Replace(&S,T,V)

初始條件:串S,T和V均已存在,

且T是非空串。

操作結(jié)果:用V替換主串S中出現(xiàn)

的所有與(模式串)T

相等的不重疊的子串。例如:假設(shè)S=abcaabcaaabca,T=bca若V=

x,則經(jīng)置換后得到

S=axaxaax若V=bc,則經(jīng)置換后得到

S=abcabcaabcStrInsert(&S,pos,T)

初始條件:串S和T存在,

1≤pos≤StrLength(S)+1。

操作結(jié)果:在串S的第pos個(gè)字符之前插入串T。例如:S=chater,T=rac,則執(zhí)行StrInsert(S,4,T)之后得到

S=characterStrDelete(&S,pos,len)

初始條件:串S存在

1≤pos≤StrLength(S)-len+1。

操作結(jié)果:從串S中刪除第pos個(gè)字符

起長度為len的子串。

ClearString(&S)

初始條件:串S存在。

操作結(jié)果:將S清為空串。

對于串的基本操作集可以有不同的定義方法,在使用高級程序設(shè)計(jì)語言中的串類型時(shí),應(yīng)以該語言的參考手冊為準(zhǔn)。

gets(str)輸入一個(gè)串;

puts(str)

輸出一個(gè)串;

strcat(str1,str2)串聯(lián)接函數(shù);

strcpy(str1,str2,k)串復(fù)制函數(shù);

strcmp(str1,str2)串比較函數(shù);

strlen(str)求串長函數(shù);例如:C語言函數(shù)庫中提供下列串處理函數(shù):在上述抽象數(shù)據(jù)類型定義的13種操作中,串賦值StrAssign、串復(fù)制Strcopy、串比較StrCompare、求串長StrLength、串聯(lián)接Concat以及求子串SubString

等六種操作構(gòu)成串類型的最小操作子集。

即:這些操作不可能利用其他串操作來實(shí)現(xiàn),反之,其他串操作(除串清除ClearString和串銷毀DestroyString外)可在這個(gè)最小操作子集上實(shí)現(xiàn)。

例如,可利用串比較、求串長和求子串等操作實(shí)現(xiàn)定位函數(shù)Index(S,T,pos)。

StrCompare(SubString(S,i,StrLength(T)),T)?

0

S串T串

T串iposn-m+1算法的基本思想為:intIndex(StringS,StringT,intpos){

//T為非空串。若主串S中第pos個(gè)字符之后存在與T相等的子串,則返回第一個(gè)這樣的子串在S中的位置,否則返回0

if(pos>0){n=StrLength(S);m=StrLength(T);i=pos;

while(i<=n-m+1){

SubString(sub,S,i,m);

if(StrCompare(sub,T)!=0)++i;

else

returni;

}//while

}//if

return0;//S中不存在與T相等的子串}//Index又如串的置換函數(shù):S串

T串V串V串pospos

subinews串sub

串的邏輯結(jié)構(gòu)和線性表極為相似,區(qū)別僅在于串的數(shù)據(jù)對象約束為字符集。

串的基本操作和線性表有很大差別。

在線性表的基本操作中,大多以“單個(gè)元素”作為操作對象;在串的基本操作中,通常以“串的整體”作為操作對象。

在程序設(shè)計(jì)語言中,串只是作為輸入或輸出的常量出現(xiàn),則只需存儲此串的串值,即字符序列即可。但在多數(shù)非數(shù)值處理的程序中,串也以變量的形式出現(xiàn)。4.2串的表示和實(shí)現(xiàn)一、串的定長順序存儲表示二、串的堆分配存儲表示三、串的塊鏈存儲表示

#defineMAXSTRLEN255//用戶可在255以內(nèi)定義最大串長

typedef

unsignedcharSstring[MAXSTRLEN+1];//0號單元存放串的長度一、串的定長順序存儲表示

按這種串的表示方法實(shí)現(xiàn)的串的運(yùn)算時(shí),其基本操作為

“字符序列的復(fù)制”。

串的實(shí)際長度可在這個(gè)預(yù)定義長度的范圍內(nèi)隨意設(shè)定,超過予定義長度的串值則被舍去,稱之為“截?cái)唷?。特點(diǎn):StatusConcat(SStringS1,SStringS2,SString&T){

//用T返回由S1和S2聯(lián)接而成的新串。若未截?cái)?則返回TRUE,否則FALSE。

returnuncut;}//Concat例如:串的聯(lián)接算法中需分三種情況處理:

T[1..S1[0]]=S1[1..S1[0]];T[S1[0]+1..S1[0]+S2[0]]=S2[1..S2[0]];T[0]=S1[0]+S2[0];uncut=TRUE;

}

if

(S1[0]+S2[0]<=MAXSTRLEN)

{//未截?cái)鄀lseif

(S1[0]<MAXSTRSIZE){//截?cái)鄀lse{//截?cái)?僅取S1)T[1..S1[0]]=S1[1..S1[0]];T[S1[0]+1..MAXSTRLEN]=S2[1..MAXSTRLEN-S1[0]];T[0]=MAXSTRLEN;uncut=FALSE;

}

T[0..MAXSTRLEN]=S1[0..MAXSTRLEN];//T[0]==S1[0]==MAXSTRLENuncut=FALSE;

}

typedefstruct{char*ch;

//若是非空串,則按串長分配存儲區(qū),

//否則ch為NULL

intlength;//串長度

}HString;二、串的堆分配存儲表示

通常,C語言中提供的串類型就是以這種存儲方式實(shí)現(xiàn)的。系統(tǒng)利用函數(shù)malloc()和free()進(jìn)行串值空間的動態(tài)管理,為每一個(gè)新產(chǎn)生的串分配一個(gè)存儲區(qū),稱串值共享的存儲空間為“堆”。

C語言中的串以一個(gè)空字符為結(jié)束符,串長是一個(gè)隱含值。

這類串操作實(shí)現(xiàn)的算法為:先為新生成的串分配一個(gè)存儲空間,然后進(jìn)行串值的復(fù)制。StatusConcat(HString&T,HStringS1,HStringS2){//用T返回由S1和S2聯(lián)接而成的新串

if(T.ch)free(T.ch);//釋放舊空間

if(!(T.ch=(char*)

malloc((S1.length+S2.length)*sizeof(char))))

exit(OVERFLOW);

T.ch[0..S1.length-1]=S1.ch[0..S1.length-1];T.length=S1.length+S2.length;

T.ch[S1.length..T.length-1]=S2.ch[0..S2.length-1];

returnOK;}//Concat

StatusSubString(HString&Sub,HStringS,

intpos,intlen){//用Sub返回串S的第pos個(gè)字符起長度為len的子串

if(pos<1||pos>S.length

||len<0||len>S.length-pos+1)

returnERROR;

if(Sub.ch)free(Sub.ch);//釋放舊空間

if

(!len)

{

Sub.ch=NULL;Sub.length=0;

}//空子串

else{}//

完整子串

return

OK;}//SubString……

Sub.ch=(char*)malloc(len*sizeof(char));Sub.ch[0..len-1]=S[pos-1..pos+len-2];Sub.length=len;三、串的塊鏈存儲表示也可用鏈表來存儲串值,由于串的數(shù)據(jù)元素是一個(gè)字符,它只有8位二進(jìn)制數(shù),因此用鏈表存儲時(shí),通常一個(gè)結(jié)點(diǎn)中存放的不是一個(gè)字符,而是一個(gè)子串。存儲密度

=數(shù)據(jù)元素所占存儲位實(shí)際分配的存儲位

#defineCHUNKSIZE80

//可由用戶定義的塊大小

typedefstructChunk{

//

結(jié)點(diǎn)結(jié)構(gòu)

charch[CUNKSIZE];

structChunk*next;

}Chunk;

typedefstruct{//串的鏈表結(jié)構(gòu)

Chunk*head,*tail;//串的頭和尾指針

intcurlen;//串的當(dāng)前長度

}LString;

例如:

在編輯系統(tǒng)中,整個(gè)文本編輯區(qū)可以看成是一個(gè)串,每一行是一個(gè)子串,構(gòu)成一個(gè)結(jié)點(diǎn)。即:同一行的串用定長結(jié)構(gòu)(80個(gè)字符),行和行之間用指針相聯(lián)接。實(shí)際應(yīng)用時(shí),可以根據(jù)問題所需來設(shè)置結(jié)點(diǎn)的大小。

這是串的一種重要操作,很多軟件,若有“編輯”菜單項(xiàng)的話,則其中必有“查找”子菜單項(xiàng)。4.3 串的模式匹配算法初始條件:串S和T存在,T是非空串,

1≤pos≤StrLength(S)。操作結(jié)果:若主串S中存在和串T值相同的子串返回它在主串S中第pos個(gè)字符之后第一次出

現(xiàn)的位置;否則函數(shù)值為0。首先,回憶一下串匹配(查找)的定義:INDEX(S,T,pos)

下面討論以定長順序結(jié)構(gòu)表示串時(shí)的幾種算法。一、簡單算法二、首尾匹配算法三、KMP(D.E.Knuth,V.R.Pratt,J.H.Morris)算法intIndex(SStringS,SStringT,intpos){

//返回子串T在主串S中第pos個(gè)字符之后的位置。若不存在,

//則函數(shù)值為0。其中,T非空,1≤pos≤StrLength(S)。

i=pos;j=1;

while(i<=S[0]&&j<=T[0]){

if(S[i]==T[j]){++i;++j;}//繼續(xù)比較后繼字符

else

{i=i-j+2;j=1;}

//指針后退重新開始匹配

}

if(j>T[0])returni-T[0];

elsereturn0;}//Index一、簡單算法

先比較模式串的第一個(gè)字符,

再比較模式串的最后一個(gè)字符,

最后比較模式串中從第二個(gè)到第n-1個(gè)字符。二、首尾匹配算法

intIndex_FL(SStringS,SStringT,intpos){sLength=S[0];tLength=T[0];i=pos;patStartChar=T[1];patEndChar=T[tLength];

while(i<=sLength–tLength+1){

if(S[i]!=patStartChar)++i;

//重新查找匹配起始點(diǎn)

else

if(S[i+tLength-1]!=patEndChar)++i;

//模式串的“尾字符”不匹配

else{}}return0;}//檢查中間字符的匹配情況

k=1;j=2;while(j<tLength&&S[i+k]==T[j])

{++k;++j;}

if(j==tLength)returni;

else++i;//重新開始下一次的匹配檢測KMP算法的時(shí)間復(fù)雜度可以達(dá)到O(m+n)

當(dāng)S[i]<>T[j]時(shí),已經(jīng)得到的結(jié)果:

S[i-j+1..i-1]==T[1..j-1]

若已知T[1..k-1]==T[j-k+1..j-1]

則有S[i-k+1..i-1]==T[1..k-1]三、KMP(D.E.Knuth,V.R.Pratt,J.H.Morris)算法定義:模式串的next函數(shù)

intIndex_KMP(SStringS,SStringT,intpos){//1≤pos≤StrLength(S)i=pos;j=1;

while(i<=S[0]&&j<=T[0]){if(j=0||S[i]==T[j]){++i;++j;}//繼續(xù)比較后繼字符

elsej=next[j];//模式串向右移動

}

if(j>T[0])returni-T[0];//匹配成功

elsereturn0;

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論