KMP算法

左神KMP算法 笔记

  1. 预处理阶段:创建部分匹配表。

    • 这一阶段是对模式字符串的预处理。目的是创建一个表,表中的每个值表示模式字符串中,直到该位置为止的字符串段的前缀和后缀的最长公共元素长度。
    • 例如,如果模式是 "ABCDAB", 部分匹配表会是 [0, 0, 0, 0, 1, 2]。这表示在第六个字符 'B' 处,有长度为 2 的相同前缀和后缀 "AB"。
  2. 搜索阶段:在文本中搜索模式。

    • 在这一阶段,算法遍历文本字符串,尝试与模式字符串匹配。
    • 当遇到不匹配的字符时,而不是简单地将模式字符串向右移动一位,算法使用部分匹配表来决定将模式字符串向右移动多远。这避免了对之前已经匹配的字符的重复检查。
    • 移动的具体位数是根据部分匹配表中的值来确定的,这个值反映了可以在模式字符串中重用的已匹配字符的数目。
  3. 匹配或失败

    • 如果模式字符串完全匹配,则在文本中找到了一个匹配项。记录匹配位置或返回匹配信息。
    • 如果到达文本字符串的末尾都没有找到完全匹配,则搜索失败。

next数组

next加速过程

加速核心

图解前面一定匹配不出

整体过程

时间复杂度

代码

vector<int> nextArray(const string& s) {
	int m = s.size();
	vector<int> ne(m, 0);
	ne[0] = -1;
	if (m == 1)
		return ne;
	ne[1] = 0;
	int i = 2, cn = 0;
	while (i < m) {
		if (s[i - 1] == s[cn])
			ne[i++] = ++cn;
		else if (cn > 0)
			cn = ne[cn];
		else
			ne[i++] = 0;
		return ne;
	}
}

int kmp(const string& s1, const string& s2) {
	int n = s1.size();
	int m = s2.size();
	vector<int> ne= nextArray(s2);
	int x = 0, y = 0;
	while (x < n && y < n) {
		if (s1[x] == s2[y]) {
			x++;
			y++;
		}
		else if (y == 0) {
			x++;
		}
		else {
			y = ne[y];
		}
		return y == m ? x - y : -1;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值