关于字符串匹配Sunday算法的个人想法

  最近看了下字符串匹配的问人对于Sunday算法比较感兴趣,介绍一下自己对于它的想法。

  切入正题。字符串S1和S2,(假定S1长度大于等于S2)要求在S1中包含S2即S1可以匹配S2。Sunny算法的基本思想如下:

  首先给分别给S1和S2两个伪指针。

FKSJDKEJKSJEBC                    即定义两个变量分别指向S1和S2的字符

i                                                               串的某一字符位置(即代码中的i和j,初始都指向字符串的首位字符)。

FSJEB

j

             

  然后进行匹配操作,即将i和j在S1和S2中分别同时移动,然后进行匹配看是否相等(如判断S1[i]与S2[j]是否相等)。之后判断的结果大致可以分为两种情况:

  一、j移动到S2末端时没有出现S1[i]与S2[j]不匹配的情况。这种情况就比较好处理即S1中包含字符串S2。

FKSJDKEJKSJEBC 

        i

FKSJD

        j

  二、j在从头至尾移动过程中出现不匹配情况。当出现不匹配情况时记录一下,依旧将i移动到字符串S1的末尾。此时分为两种情况,判断S1[i + 1]字符是否存在于S2字符串中:(下面注意,移动S2的位置其实就是移动i的位置,因为j永远从S2的0开始对照S1[i]进行匹配)

①如果存在则将S2中的最靠后的匹配S1[i + 1]的字符(注意S2可能出现多个匹配的字符,此时要使用最靠后的那个字符)移动到对应S1的位置。

FKSJDEJKSJEBC                                               FKSJDEJKSJEBC

        i i+1                                                            i   

FEJEB         这里S1[i+1]是E,将E在S2中进行匹配。                                  FEJEB            这里注意不能将S2中的第一个E移动到匹配S1的位置。

        j                                                                    j


②不存在则将j(初始化为0)移动到i+1的位置,即将S2移动到S1的i+1的位置,再次进行以上匹配操作。

FKSJDSEJKSJEBC                                                  FKSJDSEJKSJEBC

        i i+1                                                                          i

 FEJEB                 由此可以看出S1[i+1]=S不存在于S2中,                                  FEJEB           将i移动到原先i+1的下一位

         j                于是直接将S2移动到i+1的位置,即移动i                                          j

具体代码如下:

bool match(string S1, string S2) {
	int l1 = S1.length();
	int l2 = S2.length();
	int i = 0, j = 0; //两个指针分别代表指向S1和S2的位置
	if (l1 < l2) return false;  //判断S1和S2的长度是否对
	while (i <= l1 - l2) {
		int p = 0;  //标示S2中是否存在与S1不符的字符

		for (j = 0; j < l2; j++) {
			if (S1[i] != S2[j]) p = 1;   //不符合标注为1
		    i++;
		}
		if (p == 0) return true;

		int q = -1;   //标示与S1[i]匹配的位置
		for (j = 0; j < l2; j++) {
			if (S1[i] == S2[j]) q = j;
		}
		i = i - q;   //移动i的位置(其实等同于移动S2的位置,因为j永远从S2的0为开始匹配)
	}
	return false;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值