数据结构--串的模式匹配算法--C语言

Brute-Force算法

1:思路:从主串s=“s0s1s2s3…sn-1”的第一个字符开始与子串t="t0t1t2…tm-1"的第个字符进行比较, 若相等,则继续比较后续字符; 否则从主串s的第-个字符开始重新与子串t的第一个字符进行比较,若相等,则继续比较后续字符;否则从主串s的第三个字符开始重新与子串t的第一个字符进行比较;如此不断进行比较,若存在子串t中的每个字符依次和主串s中的一个连续字符序列相等,则匹配成功,函数返回子串1的第一个字符在主串、中的下标,若比较完主串s的所有字符序列后,不存在一一个 和模式串t相等的子串,则匹配失败,函数返回-1。
2:一般形式:
在这里插入图片描述
3:代码实现

int BFIndex(DString S, int start, DString T)//Brute-Force算法
{
	int i = start, j = 0, v;

	while (i < S.length && j < T.length)
	{
		if (S.str[i] == T.str[j])
		{
			i++;
			j++;
		}
		else
		{
			i = i - j + 1;//比较到不相等的时候,返回原来起始的后一个位置
			j = 0;
		}
	}
	if (j == T.length)
	{
		v = i - T.length;
	}
	else
	{
		v = -1;
	}
	return v;
}

总结:这种方法太消耗时间了。

KMP算法

思路:这个算法分两步,①先算Next[]数组②再用KMP算法。
一:模式串的Next[]:next[0]=-1;(这个是不可能出现的情况)
next[1]=0;(在1前面的数中的最大真子串)
因为t0!=t1,next[2]=0;
因为t0!=t2,next[3]=0;
因为t0=t3=‘a’,next[4]=1;
因为t1=t4=‘b’,既有t0t1=t3t4=’‘ab’’,next[5]=next[4]+1=2;
因为t2=t5=‘c’,既有t0t1t2=t3t4t5=’‘abc’’,next[6]=next[5]+1=3;
因为t3=t6=‘a’,既有t0t1t2t3=t3t4t5t6=’‘abca’’,next[7]=next[4]+1=4;
因为t4!=t7,k=next[k]=next[4]=1;有因为t1!=t7,k=next[k]=next[1]=0;再因为t0=t7=‘a’,next[8]=next[1]+1=1

在这里插入图片描述

void GetNext(DString T, int next[])
{
	int j = 1, k = 0;
	next[0] = -1;//没意义的
	next[1] = 0;
	while (j < T.length - 1)
	{
		if (T.str[j] == T.str[k])//移一次,附一次值
		{
			next[j + 1] = k + 1;//j的后面一位的前面所有字符存在的真子串
			j++;
			k++;
		}
		else if (k == 0)//模式串头
		{
			next[j + 1] = 0;
			j++;
		}
		else
		{
			k = next[k];//再次里用了KMP算法
		}
	}
}

二:KMP算法(在BF算法的基础上进行了小小的改进)

int KMPIndex(DString S, int start, DString T, int next[]){//s,主串;t,子串;start,开始的位置
	int i = start, j = 0, v;

	while (i < S.length && j < T.length){//开始比较
		if (S.str[i] == T.str[j]){//相同一起向后移
			i++;
			j++;
		}
		else if (j == 0){//模式串是串头,主串向后移一个
			i++;
		}
		else{
			j = next[j];//小小的改进,用到next[]数组
		}
	}
	if (j == T.length){//在主串中寻找到子串
		v = i - T.length;
	}
	else{
	v = -1;
    }	
	return v;
}

猜你喜欢

转载自blog.csdn.net/qq_45914759/article/details/104952749
今日推荐