KMP manacher左神算法

本文详细介绍了KMP算法中的next数组构建方法,以及如何在字符串匹配中使用它,同时提及了Manacher算法处理回文问题的步骤和代码实现。
摘要由CSDN通过智能技术生成

KMP算法

next数组含义

表示i之前的字符串前后缀相等的最大长度

主函数与回跳过程图

int getIndexof(string& s1,string& s2) {
	if (s1.empty() || s2.empty())
		return -1;
	int i1 = 0; int i2 = 0;
	 vector<int>next = getNextArray(s2);
	while (i1 < s1.size() && i2 < s2.size()) {
		if (s1[i1] == s2[i2]) {
			i1++; 
			i2++;
		}
		else if (i2 == 0)  //str2比对的位置已经无法往前跳了
			i1++;
		else
			i2 = next[i2];
	}
	//i1或者i2越界
	return i2 == s2.size() ? i1 - i2 : -1;

}

next数组建立方法

cn的含义:前缀的下一个字符的位置 和i-1位置比

现在使用的信息长度是多少

next[i++] = ++cn的意思:next[i++]=cnt+1 cnt++

cnt++是为什么:当来到下一个位置i+1时 需要用到的是cnt+1的值

vector<int> getNextArray(string& ms) {
	  if (ms.size()==1) {
		  return { -1 };
	  }
	  vector<int>next(ms.size());
	  next[0] = -1; next[1] = 0;;
	  int i = 2;  //next数组位置
	  int cn = 0;
	  while (i < next.size()) {
		  if (ms[i - 1] == ms[cn])
			  next[i++] = ++cn;

		  //当前跳到cn位置和i-1位置匹配不上
		  else if (cn > 0)   //如果不等 cn>0 cn又可以往前跳
			  cn = next[cn];
		  else
			  next[i++] = 0;  
	  }
	  return next;
}

manacher算法

step1: 将字符之间都加上特殊符号 记作“#”

step2:扩散三种情况

三种情况

1.当前位置不在回文最右边界 暴力括

2.当前位置在回文边界里

2情况根据i'状况 继续可以分类

(1)i'在L,R内部

结论:i的回文半径与i'相等

(2)i'部分在L,R外部

结论:i的回文半径是R-i

3.压线

结论:i的回文半径至少是 R-i 

是否更远需要验证

代码

伪代码

代码

string manacherString(string str) {
	string res;
	int index = 0;
	for (int i = 0; i != res.size(); i++) {
		res[i] = (i & 1) == 0 ? '#' : res[index++];
	}
	return res;

}

int maxLcpsLength(string s) {
	if (s.empty())
		return 0;
	vector<int>arr(s.size());
	int c = -1;  //中心
	int R = -1;  //回文右边界再往右的一个位置 最右有效位置是R-1
	int Max = INT_MIN;  //扩出来的最大值
	for (int i = 0; i != s.size(); i++) {
		//i至少的回文区域 先给pArr
		arr[i] = R > i ? min(arr[2 * c - i], R - i) : 1;

		while (i + arr[i] < s.size()&&i-arr[i]>-1) {
			if (s[i + arr[i]] == s[i])
				arr[i]++;
			else
				break;
		}
		if (i + arr[i] > R) {
			R = i + arr[i];
			c = i;
		}
		Max = max(Max, arr[i]);
	}
	return Max - 1;
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值