字符串匹配

1、朴素的字符串匹配算法

伪代码

View Code
1 NAIVE-STRING-MATCHER(T,P)
2 n=length(T)
3 m=length(P)
4 for(s=0;s<=n-m;++s)
5 if(P[1...m]==T[1+s,...,m+s])
6 print"Pattern occurs"
View Code
 1 char* T="acaabcsfsdfserfsdfsfwserwerfw";
2 char* P="aab";
3
4 void Naive_String_Matcher()
5 {
6 int lengthT=strlen(T);
7 int lengthP=strlen(P);
8
9 for(int i=0;i<=lengthT-lengthP;++i)
10 if(strncmp(P,T+i,lengthP)==0)
11 {
12 cout <<"Yeah";
13 return;
14 }
15 cout <<"No";
16 }

2、Rabin-Karp算法

如果字符串是数字形式。。。

已知模式P[1..m],设p表示其相应的十进制的值,类似的,对于给定的文本T[1..n],用ts 表示其长度为m的字符串T[1+s...m+s](s=0,1,...,n-m)相应的十进制数的值。当且仅当T[1+s..m+s]=P[1..m]时ts=p。

计算p的值:p=P[m]+10P[m-1]+...+10m-1P[1]

递归计算ts的值:ts+1=10(ts-10m-1T[s+1])+T[s+m+1]

有一个问题就是如果p和ts的值太大,导致不能方便进行处理。解决方式是去一个合适的素数q,来对p和ts取模

rabin karp
 1 void Rabin_Karp()
2 {
3 int lengthT=strlen(T);
4 int lengthP=strlen(P);
5
6 int d=10;
7 int q=11;
8 int h=(int)(pow((float)d,lengthP-1));
9
10 int p=0;
11 const int n=lengthT-lengthP+1;
12 int *t=new int[n];
13 t[0]=0;
14
15 for(int i=0;i<lengthP;++i)
16 {
17 p=(d*p+int(P[i]-'0'));
18 t[0]=(d*t[0]+int(T[i]-'0'));
19 }
20
21
22 for(int i=0;i<lengthT-lengthP;++i)
23 {
24 if(p==t[i])
25 {
26 if(strncmp(P,T+i,lengthP)==0)
27 cout <<"yeah"<<endl;
28 }
29 t[i+1]=(d*(t[i]-int(T[i]-'0')*h)+int(T[i+lengthP]-'0'));
30 }
31 }

 

3、字符串匹配自动机

有限自动机M定义:(Q,q0,A,∑,δ),其中:

Q:状态的有限集合

q0属于Q:初始状态

A包含于Q:接受状态集合

∑:有限的输入字母表

δ:状态转移函数

 

有限自动机M可以推导出一个函数Φ,称为终态函数,Φ(w)是M在扫描字符串w后终止时的状态。

设模式P[1..m],首先定义一个辅助函数σ,称为相应P的后缀函数,σ(x)=max{k:Pk是x的后缀}

模式P[1..m]对应的字符串匹配自动机定义如下:

(1)状态集合Q={0,1,2,...,m},初始状态q0=0,状态m是唯一的接受状态

(2)对任意状态q和字符a,状态转移函数δ(q,a)=σ(Pqa)

 

 

posted @ 2012-03-14 10:43  Cavia  阅读(298)  评论(0编辑  收藏  举报