字符串匹配之DFA

参考: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;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值