下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、實驗四:KMP算法實驗報告一、 問題描述模式匹配兩個串。二、 設計思想這種由D.E.Knuth,J.H.Morris和V.R.Pratt同時發(fā)現的改進的模式匹配算法簡稱為KMP算法。注意到這是一個改進的算法,所以有必要把原來的模式匹配算法拿出來,其實理解的關鍵就在這里,一般的匹配算法:int Index(String S,String T,int pos)/參考數據結構中的程序 i=pos;j=1;/這里的串的第1個元素下標是1 while(i=S.Length & jT.Length) return i-T.Length;/匹配成功 else return 0;匹配的過程非常清晰,關鍵是當失
2、配的時候程序是如何處理的?為什么要回溯,看下面的例子:S:aaaaabababcaaa T:ababcaaaaabababcaaa ababc.(.表示前一個已經失配)回溯的結果就是aaaaabababcaaa a.(babc)如果不回溯就是aaaaabababcaaa aba.bc這樣就漏了一個可能匹配成功的情況aaaaabababcaaa ababc這是由T串本身的性質決定的,是因為T串本身有前后部分匹配的性質。如果T為abcdef這樣的,大沒有回溯的必要。改進的地方也就是這里,我們從T串本身出發(fā),事先就找準了T自身前后部分匹配的位置,那就可以改進算法。如果不用回溯,那T串下一個位置從哪里
3、開始呢?還是上面那個例子,T為ababc,如果c失配,那就可以往前移到aba最后一個a的位置,像這樣:.ababd. ababc -ababc這樣i不用回溯,j跳到前2個位置,繼續(xù)匹配的過程,這就是KMP算法所在。這個當Tj失配后,j應該往前跳的值就是j的next值,它是由T串本身固有決定的,與S串無關。數據結構上給了next值的定義: 0 如果j=1 nextj=Maxk|1kaaab -aaab -aaab像這樣的T,前面自身部分匹配的部分不止兩個,那應該往前跳到第幾個呢?最近的一個,也就是說盡可能的向右滑移最短的長度。到這里,就實現了KMP的大部分內容,然后關鍵的問題是如何求next值?
4、先看如何用它來進行匹配操作。將最前面的程序改寫成:int Index_KMP(String S,String T,int pos) i=pos;j=1;/這里的串的第1個元素下標是1 while(i=S.Length & jT.Length) return i-T.Length;/匹配成功 else return 0;求next值,這也是整個算法成功的關鍵。前面說過了,next值表達的就是T串的自身部分匹配的性質,那么,我只要將T串和T串自身來一次匹配就可以求出來了,這里的匹配過程不是從頭一個一個匹配,而是從T1和T2開始匹配,給出算法如下:void get_next(String T,int
5、 &next) i=1;j=0;next1=0; while(i=T.Length) if(j=0 | Ti=Tj)+i;+j; nexti=j;/*(2)*/ else j=nextj; 看這個函數非常像KMP匹配的函數!注意到(2)語句邏輯覆蓋的時候是Ti=Tj以及i前面的、j前面的都匹配的情況下,于是先自增,然后記下來nexti=j,這樣每當i有自增就會求得一個nexti,而j一定會小于等于i,于是對于已經求出來的next,可以繼續(xù)求后面的next,而next1=0是已知,所以整個就這樣遞推的求出來了,方法非常巧妙。這樣的改進已經是很不錯了,但算法還可以改進,注意到下面的匹配情況:.aa
6、ac. aaaa. T串中的a和S串中的c失配,而a的next值指的還是a,那同樣的比較還是會失配,而這樣的比較是多余的,如果我事先知道,當Ti=Tj,那nexti就設為nextj,在求next值的時候就已經比較了,這樣就可以去掉這樣的多余的比較。于是稍加改進得到:void get_nextval(String T,int &next) i=1;j=0;next1=0; while(i=T.Length) if(j=0 | Ti=Tj) +i;+j; if(Ti!=Tj) nexti=j; else nexti=nextj;/消去多余的可能的比較,next再向前跳 else j=nextj;
7、三、 分析理論時間復雜性這個程序或許比想像中的要簡單,因為對于i值的不斷增加,代碼用的是for循環(huán)。因此,這個代碼可以這樣形象地理解:掃描字符串S,并更新可以匹配到T的什么位置。為什么這個程序是O(n)的? KMP的時間復雜度分析可謂攤還分析的典型。我們從上述程序的j 值入手。每一次執(zhí)行while循環(huán)都會使j減?。ǖ荒軠p成負的),而另外的改變j值的地方只有第五行。每次執(zhí)行了這一行,j都只能加1;因此,整個過程中j最多加了n個1。于是,j最多只有n次減小的機會(j值減小的次數當然不能超過n,因為j永遠是非負整數)。這告訴我們,while循環(huán)總共最多執(zhí)行了n次。按照攤還分析的說法,平攤到每次fo
8、r循環(huán)后,一次for循環(huán)的復雜度為O(1)。整個過程顯然是O(n)的。這樣的分析對于后面P數組預處理的過程同樣有效,同樣可以得到預處理過程的復雜度為O(m)。四、 原程序和調試結果package kmp;public class kmp String s=aaaaaaaa; String p=aaaab; int next=new ints.length(); /主要計算next的值 void calnext() int i,j=0; next1 = 0; next0=-1; for(i=2;is.length();i+) if(s.charAt(j)=s.charAt(i-1) nexti=nexti-1+1;j+; else if(nextj0) nexti=0; else nexti=nextj; j=nexti; /輸出實際運算次數 void display() int i=0,j=0,v; int count=0; while(is.length()&jp.length() if(s.charAt(i)=p.charAt(j) i+;j+; else if(j=0)i+; else j=nextj; count+; System.out.println(+count);
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 鋼管架租賃公司制度規(guī)范
- 高校教材建設制度規(guī)范
- 網格聯絡員制度規(guī)范
- 刷卡制度規(guī)范要求
- 油田卸油制度規(guī)范
- 幼兒園探視制度規(guī)范
- 規(guī)范填寫進出臺賬制度
- 設計公司制度規(guī)范
- 組織建設制度規(guī)范
- 診所開會制度規(guī)范
- 頸部腫塊課件
- 考查課程考核方案
- 2023年鄭州公用事業(yè)投資發(fā)展集團有限公司招聘筆試模擬試題及答案解析
- (通用版)漢字聽寫大會競賽題庫(含答案)
- GB∕T 20973-2020 膨潤土-行業(yè)標準
- 婦幼保健院工作制度(崗位職責252項)
- 盡調模范:渾水做空瑞幸的報告(中文版)
- 燃氣管道年度檢驗報告
- (完整版)外研版英語初二下冊單詞表
- 口腔扁平苔蘚PPT醫(yī)學課件
- 《設計概論》教案2022
評論
0/150
提交評論