using namespace std; /** * 变量声明和定义 * text表示文本,pattern表示要匹配的模式,a是自动机(用二维数组表示) */ string text = "aeongzngngnng"; string pattern = "nng"; const string::size_type m = pattern.size(); int **a;
//动态分配内存,并将元素初始化为0 void init(){ a = new int* [m+1]; for(size_t i=0;i!=m+1;i++) { a[i] = new int[text.size()](); } }
//判断是否为后缀,根据定理σ(xa) = σ(Pqa).只需判断Pk是否是Pqa的后缀 bool is_suffix(int k,int q,char a) { if(pattern[k-1]!=a) { return false; } for(int i=k-2,j=q-1;i>=0&&j>=0;--i,--j) { if(pattern[i]!=pattern[j]) return false; } return true; }
//填充自动机数组 void compute_transition_function() { for(string::size_type p=0;p<=m;++p) { for(string::size_type t=0;t!=text.size();++t) { //k取值根据σ(xa) ≤ σ(x) + 1. int k = min(m+1,p+2); do { --k; }while(k>0&&!is_suffix(k,p,text[t])); a[p][t] = k; } } for(string::size_type p=0;p<=m;++p) { for(string::size_type t=0;t!=text.size();++t) { cout<<a[p][t]<<flush; } cout<<endl; } }
//匹配模式 void finit_automic_matcher() { string::size_type q = 0; for(string::size_type t=0;t!=text.size();t++) { q = a[q][t]; if(q==m) { cout<<t-m+2<<endl; } } }
//删除数组释放内存 void deleteArr() { for(size_t i=0;i<=m;i++) { delete []a[i]; } delete []a; }
//主函数 int main() { init(); compute_transition_function(); finit_automic_matcher(); deleteArr(); return 0; }