串的模式匹配算法

串:就是内容受限制的线性表,其只能存储字符类型

串的模式匹配算法:简而言之就是从一个目标串中去找到其中一部分字符所组成的子串的方法

例如:主串为abcde,要查找的字符串为bc,

查找方法有两种:

1、BF算法:

 从主串中的第一个字符开始依次与子串(要查找的串)中的字符开始进行匹配。

 2、KMP算法:采用next【】函数,和nexval【】函数

BF算法:

int Index_BF(SString S, SString T) {
	int i = 1, j = 1;
	while (i<=S.length && j<=T.length)
	{
		if (s.ch[i] == t.ch[j]) {
			++i;//主串和子串依次匹配下一个字符
			++j;
		 }
		else {   //主串、字串指针回溯重新开始下一次匹配
			i = i - j + 2;
			j = 1;
		}
		if (j >= T.length)  //匹配成功则返回第一个字符的下标
			return i - T.length;
		else  //匹配不成功返回0
			return 0;
	}
}

代码说明:其中的S为主串,T为模式串,(两个串都是只存储了字符的线性表),且字符的比较位置都是从1开始,i代表字符在主串中的位置,j代表字符在模式串中的位置

匹配过程为:

两个串都从位置1开始比较开字符是否相同,若是相同则都往后移一位继续比较

若是不相同,则主串的比较位置回溯到:i-j+2;子串则从头开始(位置1),两个串又重新开始比较,循环往复直到匹配成功,或者是匹配失败。

 

KMP算法:

int index_KMP(sstring s, sstring t) {
	i = 1, j = 1;
	while (i < s.length && j < t.length) {
		if (j == 0 || s.ch[i] == t.ch[j]) {
			i++;
			j++;
		}
		else
			j = next[j]; //i不变j回溯
	}
	if (j > t.length)
		return i - t.length; //匹配成功
	else return 0;  //匹配失败
}

代码说明:KMP算法大致和BF算法不同之处在于,当发现字符不匹配时主串i不在回溯而是停留在匹配时的位置 ,回溯的仅仅是子串j的位置,这就由代码中的next【】决定了,具体代码应用时需要将上述代码中的next换成调用其的函数(上述代码只是说明作用)

 

next【】:

void get_next(SString T, int& next[]) {
	int i = 1;
	int j = 0;
	next[1] = 0;
	while (i < T.length) {
		if (j == 0 || T.ch[i] == T.ch[j]) {
			++j;
			++i;
			next[i] = j;
		}
		else
			j = next[j];
	}
}

说明:next【】的值只与子串有关

1、当子串中j=1时:next[j]=0

2、当子串中的:j!=1时,将自身所在位置的元素除外,前面所有的字符所组成的串对称比较从1个字符前后比较依次增加看最多有几个字符相同则:n就为多少,而K-1=n,next[j]=K;

3、其他情况:next[j]=1;

例子:一个子串S为:abababa

j           1   2   3   4   5   6   7

S          a   b  a   b   a   b    a

next     0   1   1   2   3   4   3 

j=1时:next=0;

j=2时:前面只有a一个无法比较,next=1;

j=3时:前面为ab则前后比较发现无相同字符,所以n=0,k=0+1,next=1

j=4时:前面为aba,从单字符开始比较a 和 a相同 n=1,在从两个字符开始比较ab和ba不相同

所以n=1,k=1+1,next=2

j=5时:前面为abab,从单字符开始比较a和b 不相同,在从两个字符开始比较ab和ab相同所以n=2

k=2+1,next=3

后面便是依次类推

而在next函数的改进的基础上得出了nextval函数

nextval【】:

void get_nextval(sstring t, int& nextval[]) {
	i = 1;
	nextval[1] = 0;
	j = 0;
	while (i<t.length) {
		if (j == 0 || t.ch[i] == t.ch[j]) {
			++i;
			++j;
			if (t.ch[i] != t.ch[j]) {
				nextval[i] = j;
			}
			else
				nextval[i] = nextval[j];
		}
		else j = nextval[j];
	}
}

 总而言之就是:j=1时,nextval=0,

其他情况就是:以当前位置所对应的next的值去找到对应位置j看其位置上的字符是否和它相同相同则nextval取其位置的next的值作为自身值,反之则就取原本位置的next值,如上述例子所说

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值