字串匹配KMP演算法

來源:互聯網
上載者:User

所謂的字串匹配是指在一個字串S中找出另外一串字串P的位置。 1 字串匹配簡單演算法 字串匹配簡單演算法是指,從本文S和模式P的第一個字元出發,將S和P的字元依次逐個進行比較,如果模式P中所有的字元都與S中的字串匹配完,則說明在本文S中找到了模式P的字串,返回位置就可以了,如果沒有匹配完成,則將模式P沿著本文S向後移了一個位置,再從模式P的第一個字元開始以此進行比較,如果沒有找到則返回-1。 例如本文S為“ABABABCCA”,P為“ABABC”.具體實現代碼如下:

#include <iostream>#include<string>using namespace std;int fstr(string ,string);int main(){string str1,str2;cout<<"請輸入本文S:";cin>>str1;cout<<"請輸入模式P:";cin>>str2;cout<<fstr(str1,str2);return 0;}int fstr(string S ,string P){int m=S.size();int n=P.size();int len=0;int i=0,j=0;for (len=0;len<=m-n;len++){i=len;j=0;while((i<m)&&(j<n)&&(S[i]==P[j])){++i;++j;}if (j==n){return len+1;}}return -1;}
2 字串匹配KMP演算法 KMP演算法是指,在字串匹配的過程中,如果發現本文S與模式P中有字元不匹配了,找到一種模式P沿本文S向後移動的規則,以便使得本文S中失去匹配的字元以前的字元不再參與比較,即只從當前失去匹配的字元開始與模式P中的字元繼續進行比較。例如如圖所示:
當發現模式P中第7個字元C與本文S的第7個字元X不相符時,將模式P沿著本文S 向後移動2個字元單位,接著比較模式P中的第5個字元與本文S中的第7個字元是否相等。為什麼可以這樣呢。因為很明顯的發現模式P的第3-6個字元與其第1-4個字元是相同的,如下圖所示。
於是我們可以定義一個這樣的函數,針對需要匹配的字串,j=F(i),其中i表示當第i個字元不匹配時,j表示我們需要退回到從第j個字元開始比較,例如上例中的i就表示的是7,j就表示的是5;規定的是1=F(1),用遞推的規律求F(i);假如前面的F(1)=1~F(i-1)=j均已求出,現在來求F(i);
如圖所示,當F(i-1)=j表示P[1]~P[j-1]與P[i-j]~P[i-2]是對應相等的,當P[i-1]與P[j]也相等時,很明顯F(i)=F(i-1)+1;,若P[i-1]與P[j]不相等時,則需要退一步從F(j)=k來考慮;
考慮當P[i-1]與P[k] 相等時,很明顯F(i)=F(k )+1;,若P[i-1]與P[k ]不相等時,則需要退一步從F(k )=x 來考慮;只要K大於1,當k退回為1時,則令 F(i)= 1;重複上面的步驟,找到F(i);根據上面的演算法可以得出模式P等於“ABABABCCA”時,對應的回溯位置為F(1)=1;F(2)=1;F(3)=1;F(4)=2;F(5)=3;F(6)=4;F(7)=5;F(8)=1;F(9)=1;具體的代碼如下:
#include <stdio.h> #include <string.h>#include <stdlib.h> int pskmp(char s[],char p[]);void pflink(char p[],int *flink);int main(){char s[]="ACCAABCCA";char p[]="BCCA";int n=pskmp(s,p);printf("%d",n);return 0;}int pskmp(char s[],char p[]){int m=strlen(s);int n=strlen(p);int i=0,j=0,flag=0;int* flink;flink=(int *)malloc(n*sizeof(int));pflink(p,flink);while(i<m&&j<n&&flag==0){while (j>0&&(p[j]!=s[i])) j=flink[j];if (p[j]!=s[i])//由於模式P的第一個位置就與本文S不匹配時,則直接向右移動一個i++;    if (j==n-1) flag=1;else{i++;j++;}}if (flag==1) i=i-n+2;else i=-1;free(flink);return i;}void pflink(char p[],int *flink){int n=strlen(p),i=2,j;flink[0]=0,flink[1]=0;//由於數組的起始位置為0,所以第一個位置也由1變為0while (i>0&&i<n){j=flink[i-1];while (j>0&&(p[i-1]!=p[j])) j=flink[j]; if (p[i-1]==p[j])//由於數組的起始位置為0,為了找到第一個1,所以必須再次判斷{flink[i]=j+1;}else flink[i]=0; //當未找到匹配時直接從第一個位置0開始i++;}}









聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.