[演算法]兩種字串匹配演算法(索引法,KMP演算法)對比,C語言實現
KMP演算法 是Knuth, Morris, Pratt三位前人提出的字串快速匹配演算法,簡稱KMP演算法,典的演算法了,還有以後發展的BM 和AB-BM演算法,別急啊,這個下次再講,最近是沒時間寫部落格了,原理很簡單,就是使用了額外的數值記錄索引匹配的次數,然後根據這個結果進行結果計算的方法,不知道?可以參閱
http://www.chinaitpower.com/A/2003-01-04/45995.html
索引法,就數最簡單的字串的匹配演算法,原理就是,一個一個試,找到第一個以後,再看是否匹配第二個了,一直到字串末尾,很經典的演算法。
下面我們作個簡單對比,看程式碼:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
/*getnext*/
void getNext(char p[],int next[]){
int i, j, slen;
slen = strlen(p);
i = 0;
j = -1;
next[0] = -1;
while(i < slen br>
if((j == -1) || (p[i] == p[j])){
i++;
j++;
next[i] = j;
}/*if*/
else{
j = next[j];
}/*else*/
}/*while*/
}/*get_next*/
int kmp(char s[], char p[], int pos, int next[]) {
/*KMP演算法*/
int i, j, slen, plen;
i = pos;
j = 0;
slen = strlen(s);
plen = strlen(p);
while((i < slen j plenbr>
if((j == -1) || (s[i] == p[j])){
i++;
j++;
}
else
{
j = next[j];
}
}/*while*/
if(j >= plen) {
return (i-plen);
}/*if*/
else {
return -1;
}/*else*/
}/*kmp*/
int index(char s[], char p[], int pos){
/*索引匹配法*/
int i, j, slen, plen;
i = pos;
j = 0;
slen = strlen(s);
plen = strlen(p);
while((i < slen j plenbr>
if((s[i] == p[j])){
i++;
j++;
}/*if*/
else{
i = i-j+1;
j = 0;
}/*else*/
}/*while*/
if(j >= plen) {
return (i-plen);
}
else {
return -1;
}
}/*index*/
void main(){
char s[] = "acbaabcaacabaabaabcacaabc"; /*測試字串*/
char p[] = "abaabca";
int next[50];
getNext(p, next);
printf("found index at %dn", kmp(s, p, 0, next));
printf("found index at %dn", index(s, p, 0));
}/*main*/
KMP演算法是kmp()這個函式,INDEX演算法是index()函式,相信諸位看出來了吧,KMP要多一個計算陣列的,這也是精髓所在,也是效率所在,提高了一個數量級,諸位知道這樣提高效率的結果了吧,不過,最壞的情況可能要浪費N多的空間了,好了,演算法提供完,演算法部分大家要是不懂的話,可以直接留言,或者跟我聯絡
附:來自網路的KMP匹配演算法C++實現演算法, 源自http://www.chinaitpower.com/A/2003-01-04/45995.html,作者莫怪,借用一下給大家參考,個人比較喜歡純C,C++最近不怎麼使用了
KMP演算法查詢串S中含串P的個數count
#include
#include
#include
using namespace std;
inline void NEXT(const string& T,vector& next)
{
//按模式串生成vector,next(T.size())
next[0]=-1;
for(int i=1;i
int j=next[i-1];
while(T[i]!=T[j+1]&& j>=0 )
j=next[j] ; //遞推計算
if(T[i]==T[j+1])next[i]=j+1;
else next[i]=0; //
}
}
inline string::size_type COUNT_KMP(const string& S,
const string& T)
{
//利用模式串T的next函式求T在主串S中的個數count的KMP演算法
//其中T非空,
vector next(T.size());
NEXT(T,next);
string::size_type index,count=0;
for(index=0;index
int pos=0;
string::size_type iter=index;
while(pos
if(S[iter]==T[pos]){
++iter;++pos;
}
else{
if(pos==0)++iter;
else pos=next[pos-1]+1;
}
}//while end
if(pos==T.size()&&(iter-index)==T.size())++count;
} //for end
return count;
}
int main(int argc, char *argv[])
{
string S="abaabcacabaabcacabaabcacabaabcacabaabcac";
string T="ab";
string::size_type count=COUNT_KMP(S,T);
cout<<
system("PAUSE");
return 0;
}
--------------------------------------------------------------------------------------
- 版權宣告:
- 如在本頁面內無特別說明,本文內容均為[李大仁部落格]原創,本文版權歸[李大仁部落格]所有。
- 歡迎轉載,轉載請務必在文章頁面明顯位置提供原文連結並註明出處。歡迎您在轉載本文時保留本段宣告。
- 文章標題:C語言實現的兩種字串匹配演算法包括索引法,KMP演算法
- 獨立部落格:李大仁部落格
- 永久連結:http://www.lidaren.com/archives/226
--------------------------------------------------------------------------------------
以上內容由部落格自動釋出工具自動釋出,最終顯示內容和效果會與原文內容有所偏差,敬請諒解。