参考:http://www.cnblogs.com/alexqdh/archive/2011/05/23/2047015.html
原文中对二维数组理解有误,导致代码里面有bug,已经修改,一并修改了代码中个人认为不是很方便阅读的地方。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ALPHABET_LEN 53
#define MIN(x,y) ((x)<=(y)?(x):(y))
static const char alphabet[ALPHABET_LEN]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
int IsSuffix(char *pattern, int k, int q, char a)
{
int cmp;
char tmp[q+1];
tmp[q]=a;
strncpy(tmp, pattern, q);
//#define DBG
#ifdef DBG
int i = 0;
printf("pattern:");
for(i = 0; i < k; i++)
printf("%c ", pattern[i]);
printf("\n");
printf("tmp + q - (k - 1):");
for(i = q - (k - 1); i < k; i++)
printf("%c ", tmp[i]);
printf("\n");
#endif
cmp=strncmp(pattern, tmp + q - (k - 1), k);
if(!cmp)
return 1;
else
return 0;
}
/*
int *Ptr[5] <==> int Ptr[5][x];--->指针数组
int (*Ptr)[5] <==> int Ptr[x][5];--->数组指针
*/
void create_automata(int*** array,char pattern[])
{
int i,j,k;
int pattern_len=strlen(pattern);
int x=pattern_len+1;
int y=ALPHABET_LEN;
*array=(int**)malloc(sizeof(int)*y);
if(!*array)
return;
for(i=0; i<x; i++){
(*array)[i] = (int*)(malloc(sizeof(int*) * x));
if(!(*array)[i]){
while(--i>=0)
free((*array)[i]);
free(*array);
return;
}
}
for(i=0; i<=pattern_len; i++){
for(j=0; j<ALPHABET_LEN; j++){
k = MIN(pattern_len, i + 1);
while(k && !IsSuffix(pattern, k, i, alphabet[j]))
--k;
(*array)[i][j]=k;
}
}
for(i=0; i< pattern_len+1; i++){
for(j=0; j<ALPHABET_LEN; j++)
printf("%d ", (*array)[i][j]);
printf("\n");
}
}
int SearchChar(char a)
{
int i=0;
while(i < ALPHABET_LEN - 1){
if(a == alphabet[i])
return i;
i++;
}
return -1;
}
int DFAMatcher(char target[], int** array,char *pattern){
int i = 0, q = 0, position = 0;
int n=strlen(target);
int m=strlen(pattern);
for(i=0; i<n; i++){
position=SearchChar(target[i]);
if(position<0){
fprintf(stderr,"字符[%c]不存在\n",target[i]);
return -1;
}
q=array[q][position];
if(q==m){
printf("find!\n");
break;
}
}
if(q!=m){
printf("unfind\n");
i=-1;
}
return i;
}
void Delete(int*** array,char pattern[])
{
int i;
int m=strlen(pattern);
for(i = 0; i < m + 1; ++i)
free((*array)[i]);
free((*array));
return;
}
int main(int argc, char* argv)
{
int i;
int **dfa_array;
char source[100]="defabcababacaghijkl";
char pattern[10]="ababaca";
create_automata(&dfa_array,pattern);
int end=DFAMatcher(source,dfa_array,pattern);
int first=end-strlen(pattern)+1;
if(end>=0){
printf("source string:%s\n",source);
printf("pattern:%s\n",pattern);
for(i=0; i<strlen(source); i++){
if(i==end || i==first)
printf("|");
else
printf(" ");
}
printf("\nEnd Position:%d\n",end);
}
//Delete(&dfa_array,b);
return 1;
}