/* ac算法的实现 */ #include <stdio.h> #include <conio.h> #include <string> using namespace std; #define MAX_STATE 100 //自动机最大状态数 #define MAX_SYMBOL 256 //匹配的字符数 可以匹配所有的ASCII码 #define MAX_MODE 20 //最大模式串数 int GoAndFail[MAX_STATE][MAX_SYMBOL]; //状态转移表--DFA 包括转向函数和失效函数 int F[MAX_STATE] ; int output[MAX_STATE]; //在该状态的输出模式串 -1表示没有输出 unsigned int statecount; //总状态数-1 unsigned int modecount; //模式串数-1 struct mode{ unsigned int statenum; //模式串数 string modestring[MAX_MODE]; //在该状态时匹配的模式串 }match[MAX_MODE]; void init() {//初始化全局变量 int i,j; statecount = 1; modecount = 0; for (i = 0 ; i < MAX_MODE; i++ ) { match[i].statenum = 0; for (j = 0 ; j < MAX_MODE; j++) { match[i].modestring[j] = ""; } } for (i = 0 ; i < MAX_STATE; i++) { output[i] = -1; F[i] = 0; for (j = 0 ; j < MAX_SYMBOL; j++) { GoAndFail[i][j] = 0; } } } void go() { u_int c; u_int currentstate ; string str = "" ; //当前模式串 bool start = true; //获取输入并得到转向函数G printf("请输入模式串集(允许中文 以空格分隔每个串,以回车结束):"); while((c = getchar()) != (u_int)'/n') { if (c != (u_int)' ') { if (start) { start = false; modecount ++; currentstate = 0; str = ""; } str += c; if(GoAndFail[currentstate][c] == 0) { GoAndFail[currentstate][c] = statecount ; currentstate = statecount; statecount ++; } else currentstate = GoAndFail[currentstate][c]; } else { match[modecount].statenum = 1; match[modecount].modestring[0] = str; output[currentstate] = modecount; start = true; if (modecount == MAX_MODE) { printf("允许输入的最多模式串数为 %d",MAX_MODE); goto END; } } } match[modecount].statenum = 1; match[modecount].modestring[0] = str; output[currentstate] = modecount; return; END: printf("Press any key to continue..."); c = getch(); return; } void addOutPut(u_int sstate,u_int dstate) {//把sstate状态的输出集添加到dstate状态的输出集中 int s = output[sstate]; int d = output[dstate]; u_int k; if ( s >= 0 && d >= 0) { for (k = 0 ; k < match[s].statenum ; k++) {//将输出集s添加到输出集d中结尾,这里没有考虑如果两个输出集有相同元素的情况 match[d].modestring[match[d].statenum] = match[s].modestring[k]; match[d].statenum++; } } else if (s >= 0 && d < 0) { output[dstate] = s; } } void fail() { u_int i,j,t; //以下为求失效函数F for(i = 1 ; i < statecount; i++) { for (j = 0 ; j < MAX_SYMBOL; j++) { t = GoAndFail[i][j]; if ( t!= 0) { F[t] = GoAndFail[F[i]][j]; addOutPut(F[t], t); } } } //打印失效数F /*for (i = 0 ; i < statecount; i++) { printf("F(%u) = %u/n", i,F[i]); } */ //打印输出集 for (i = 0 ; i < statecount; i++) { if (output[i] != -1) { for (j = 0 ; j < match[output[i]].statenum; j++) { printf("Output(%u) = %s/n",i,&match[output[i]].modestring[j][0]); //cout } } } } void prec() {//预处理阶段 u_int currentstate = 1; //u_short i; //初始化变量 init(); //建立转向函数 go(); //建立失效函数 fail(); } bool AC(u_char c,bool rst) { static u_int currentstate = 0; u_int state; u_int j; if (rst) {//复位 重新开始匹配 currentstate = 0; } if (c < MAX_SYMBOL) { state = GoAndFail[currentstate][c]; if (state == 0) { currentstate = GoAndFail[F[currentstate]][c]; } else { currentstate = state; } if (output[currentstate] != -1) { for (j = 0 ; j < match[output[currentstate]].statenum; j++) { printf("Match string with %s/n", &match[output[currentstate]].modestring[j][0]); return true; } } } return false; } void test_of_AC() { u_char c; printf("请输入需要匹配的字符串:"); while ((c = getchar()) != (u_int)'/n') { AC(c,false); } } AC状态机简单实现