Aho-Corasick自动机算法(简称AC自动机)1975年产生于贝尔实验室。该算法应用有限自动机巧妙地将字符比较转化为了状态转移。
Aho-Corasick自动机算法(简称AC自动机)1975年产生于贝尔实验室。该算法应用有限自动机巧妙地将字符比较转化为了状态转移。
该算法的基本思想是这样的:
在预处理阶段,AC自动机算法建立了三个函数,转向函数goto,失效函数failure和输出函数output,由此构造了一个树型有限自动机。
在搜索查找阶段,则通过这三个函数的交叉使用扫描文本,定位出关键字在文本中的所有出现位置。
此算法有两个特点,一个是扫描文本时完全不需要回溯,另一个是时间复杂度为O(n),时间复杂度与关键字的数目和长度无关。
树型有限自动机包含一组状态,每个状态用一个数字代表。状态机读入文本串y中的字符,然后通过产生状态转移或者偶尔发送输出的方式来处理文本。树型有限自动机的行为通过三个函数来指示:转向函数g,失效函数f和输出函数output。
主要文件三个acAlgorithm.cpp,ac.h, ac.cpp其他的都是系统生成的,文件stdafx.h中有可能需要增加几个头文件。
模式集文件是一行一个模式的格式,支持中文
///
///
//文件名acAlgorithm.cpp :定义控制台应用程序的入口点。
//
#include"stdafx.h"
intmain(int argc, char* argv[])
{
charout[MAX_LENGTH_FILE_NAME] = {'\0'};
charptn[MAX_LENGTH_FILE_NAME] = {'\0'};
charmch[MAX_LENGTH_FILE_NAME] = {'\0'};
ifstream fptn,fmch;
ofstream fout;
struct AC_State root;
chara_model[MAX_LENGTH_PATTERN]={'\0'};
charisContinue;
//参数分析
switch(argc)
{
case 2:
memcpy(mch, argv[1],strlen(argv[1]));
memcpy(ptn, "pattern",strlen("pattern"));
memcpy(out, "output",strlen("output"));
break;
case 3:
memcpy(mch, argv[1],strlen(argv[1]));
memcpy(ptn, argv[2],strlen(argv[2]));
memcpy(out, "output",strlen("output"));
break;
case 4:
memcpy(mch, argv[1],strlen(argv[1]));
memcpy(ptn, argv[2],strlen(argv[2]));
memcpy(out, argv[3],strlen(argv[3]));
break;
default:
cout<
exit(0);
}
/*
memcpy(mch, "test",strlen("test"));
memcpy(ptn, "pattern",strlen("pattern"));
memcpy(out, "output",strlen("output"));
*/
cout<
//初始化状态树
init(&root);
fptn.open(ptn);
文件:
源代码及可执行文件.rar
大小:
182KB
下载:
if(fptn.fail())
{
cout<
exit(0);
}
//将模式串一个个加入到状态树中,并得出部分输出节点
while(fptn.getline(a_model, MAX_LENGTH_PATTERN))
{
if(strlen(a_model)>MAX_LENGTH_PATTERN)
{
cout<
exit(0);
}
addPattern(&root, a_model, strlen(a_model));
memset(a_model, 0, MAX_LENGTH_PATTERN);
}
fptn.close();
//得到每个状态节点的失效函数,并得到全部的输出节点
getFailFunc(&root);
L:
fmch.clear();
fmch.open(mch);
if(fmch.fail())
{
cout<
exit(0);
}
fout.clear();
fout.open(out);
if(fout.fail())
{
cout<
exit(0);
}
//执行搜索
acSearch(&root, &fmch, &fout);
fmch.close();
fout.close();
cout<
cin>>isContinue;
if(isContinue == 'y' || isContinue == 'Y')
{
cout<
memset(mch, 0, MAX_LENGTH_FILE_NAME);
memset(out, 0, MAX_LENGTH_FILE_NAME);
cin>>mch>>out;
goto L;
}
cout<
acFree(&root);
return 0;
}
//
//
//
//文件名ac.h
//
#pragmaonce
#include
#include
#include
#include
#include
#defineBUFSIZE4096//读文件缓冲区大小
#defineMAX_NUM_OF_PATTERN32//模式的最大数量
#defineMAX_NUM_OF_GOTO256//转向指针数量的最大值
#defineMAX_LENGTH_FILE_NAME128//文件名最大长度
#defineMAX_LENGTH_PATTERN128//模式的最大长度
usingnamespace std;
typedefstruct AC_State
{
int state_no;//状态的编号,没有实际的用处,可以用来模拟老师课件上的输出
intdepth;//深度
int is_final_state;//判断该节点是否为楼阁终态
int output[MAX_NUM_OF_PATTERN];//输出函数值,对应模式,可能有多个
int num_of_goto;//有多少个节点
string str;//存储从树根到该节点的字符序列,便于调试
struct AC_State *Goto[MAX_NUM_OF_GOTO]; //转向指针
struct AC_State *failure;//失效指针
} AC_State;
voidinit(struct AC_State *state);//初始化
intaddPattern(struct AC_State *root, const char* pattern, int length);//将一个模式加入并构建转向函数
voidgetFailFunc(struct AC_State *root);//求失效指针
intacSearch(struct AC_State *root, ifstream *_if, ofstream *out);//执行匹配
voidfinalAssign(int *t, int *s);
voidacFree(struct AC_State *root);