kmp 算法的一种代码实现

本文档详细介绍了KMP算法的代码实现,包括简单匹配函数、next数组和优化后的nextval数组,通过实例演示如何利用KMP算法进行字符串匹配,以及优化过程。适合进一步理解复杂匹配问题的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kmp 算法的一种代码实现

本文档仅提供代码实现,有注释,但由于 kmp 算法理解的困难性,深入理解可能还需参考一些其他资料。

在这里插入图片描述

源码如下

#include<iostream>

//简单匹配
int index(std::string&, std::string&);

// next[]
void get_next(std::string&, int next[]);

// 优化后 nextval[]
void get_nextval(std::string&, int next[]);

// kmp 算法
int kmp(std::string&, std::string&);

// 主函数
int main() {
	std::string s1{ "daabaabcabajkfajlaj" }, s2{ "abaabcaba" };
	std::cout << "测试串:" << s1 << '\n';
	std::cout << "模式串:" << s2 << std::endl;
	std::cout << "简单匹配得出匹配下标:" << index(s1, s2) << '\n';
	std::cout << "kmp 算法匹配得出匹配下标:" << kmp(s1, s2) << '\n' << std::endl;
	system("pause");
	return 0;
}

// 简单匹配
int index(std::string& Str, std::string& str) {
	if (str.length() > Str.length()) return 0;
	// i 为主串 Str 下标,j 为子串 str 下标,k 为每次匹配开始位置
	size_t i = 0, j = 0, k = 0;
	while (i < Str.length() && j < str.size()) {
		if (Str[i] == str[j]) {
			++i; ++j;
		}
		else {
			j = 0;
			// 匹配失败,将主串 i 挪到下一位再开始比较
			i = ++k;
		}
	}
	if (j >= str.size() - 1) // 注意这一步的判断
		return k;
	else return -1;
}

// next[]
void get_next(std::string& str, int next[]) {
	int i = 0, j = -1;
	next[0] = -1;
	while (i < str.size()) {
		if (j == -1 || str[i] == str[j]) {
			++i; ++j;
			next[i] = j;
		}
		else j = next[j];  // 回退
	}
}

// 优化后 nextval[]
void get_nextval(std::string& str, int next[]) {
	int i = 0, j = -1;
	next[0] = -1;
	while (i < str.size()) {
		if (j == -1 || str[i] == str[j]) {
			++i; ++j;
			if (str[i] != str[j]) next[i] = j;
			else next[i] = next[j];
		}
		else j = next[j];  // 回退
	}
}

// kmp 算法
int kmp(std::string& str, std::string& substr) {
	const int size = 100;
	int next[size];
	get_next(substr, next);
	// get_nextval(substr, next);
	// 打印 next 数组
	std::cout << "next 数组:\n";
	for (size_t i = 0; i < substr.size(); ++i) {
		std::cout << next[i] << ' ';
	}
	std::cout << std::endl;
	int i = 0, j = 0;
	int sublen = substr.size();  // 这里要注意有符号和无符号的比较!!!
	std::cout << "kmp 时模式串下标j的变化\n";
	while (i < str.size() && j < sublen) {
		if (j == -1 || str[i] == substr[j]) {
			++i; ++j;
		}
		else {
			// 失败,模式串右移
			j = next[j];
		}
		std::cout << "j = " << j << ' ';
	}
	std::cout << std::endl;
	if (j >= substr.size())
		return i - substr.length();
	else return -1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值