資料結構 順序串的各種模式匹配演算法
阿新 • • 發佈:2019-02-12
如圖效果:
#include <iostream> #include<stdio.h> #include<string.h> using namespace std; #define MaxSize 100 int next[MaxSize],nextval[MaxSize]; typedef struct { char data[MaxSize]; int length; } SqString; void StrAssign(SqString &s,char cstr[]) { int i; for(i=0; cstr[i]!='\0'; i++) s.data[i]=cstr[i]; s.length=i; } void DispStr(SqString s) { int i; for(i=0; i<s.length; i++) printf("%c",s.data[i]); printf("\n"); } ///簡單匹配演算法即BF演算法 int BFIndex(SqString s,SqString t) { int i=0,j=0; while(i<s.length&&j<t.length) { if(s.data[i]==t.data[j]) { i++; j++; } else { i=i-j+1; j=0; } } if(j>=t.length) return (i-t.length); else return -1; } ///KMP演算法中求t串的next值 void getnext(SqString t,int next[]) { int i=0,j=-1; next[0]=-1; while(i<t.length) { if(j==-1||t.data[i]==t.data[j]) { i++; j++; next[i]=j; } else j=next[j]; } } ///KMP演算法 int KMPIndex(SqString s,SqString t) { int i=0,j=0; getnext(t,next); while(i<s.length&&j<t.length) { if(j==-1||s.data[i]==t.data[j]) { i++; j++; } else j=next[j]; } if(j>=t.length) return i-t.length; else return -1; } ///改進後KMP演算法中求t串的next值 void getnextval(SqString t,int next[]) { int i=0,j=-1; next[0]=-1; while(i<t.length) { if(j==-1||t.data[i]==t.data[j]) { i++; j++; if(t.data[i]!=t.data[j]) next[i]=j; else next[i]=next[j]; } else j=next[j]; } } ///改進後的KMP演算法 int KMPIndex1(SqString s,SqString t) { int i=0,j=0; getnextval(t,next); while(i<s.length&&j<t.length) { if(j==-1||s.data[i]==t.data[j]) { i++; j++; } else j=next[j]; } if(j>=t.length) return i-t.length; else return -1; } int main() { int j; SqString s,t; StrAssign(s,"abcabcdabcdeabcdefabcdefg"); StrAssign(t,"abcdeabcdefab"); printf("串s:"); DispStr(s); printf("\n"); printf("串t:"); DispStr(t); printf("\n"); printf("t串在s串中的位置=%d\n",BFIndex(s,t)); getnext(t,next);///求next值 getnextval(t,nextval);///求nextval值 printf("j "); for(j=0;j<t.length;j++) printf("%4d",j); printf("\n"); printf("t[j] "); for(j=0;j<t.length;j++) printf("%4c",t.data[j]); printf("\n"); printf("next "); for(j=0;j<t.length;j++) printf("%4d",next[j]); printf("\n"); printf("nextval"); for(j=0;j<t.length;j++) printf("%4d",nextval[j]); printf("\n"); printf("kmp演算法中t在s中出現的位置=%d\n",KMPIndex(s,t)); printf("改進後的kmp演算法中t在s中出現的位置=%d\n",KMPIndex1(s,t)); return 0; }
哈哈,好高興,終於理解了KMP
BF可以直接返回模式串在主串中的位置,簡單易懂但是效率太低
KMP先求t串的next值,然後通過KMPIndex()呼叫getnext()函式返回匹配位置
改進後的KMP與KMP只是next取值時有所不同,也是通過KMPIndex1()呼叫getnextval()返回匹配位置