0
点赞
收藏
分享

微信扫一扫

作文以记之 ~ 实现strStr()

作文以记之 ~ 实现strStr

0、前言

本篇博客依然是一篇题解,具体题目可 点击此处 进行查看!具体代码以及其他内容可 点击此处 进行查看!

其实这个题目主要是练习 KMP 算法的,所以下述两种解法中会有专门的应用!

1、题目描述

在这里插入图片描述

2、解题思路

2.1 方法1 ~ 暴力遍历

2.1.1 思路

从两个字符串的首元素开始遍历,当完全遍历到与模式串相符合时,返回此时的起始位置。该思路简单,实现也简单,但相比较下会浪费较多的资源,因为一旦不满足模式串,就需要重新开始遍历。

2.1.2 程序代码

#include<iostream>
#include<string>
#include<vector>
using namespace std;

/* 方法1 ~ 暴力遍历*/
int strStr(string haystack, string needle) 
{
	int n = haystack.size(), m = needle.size();
	if (m <= 0)
		return 0;
	int i, j;
	for (i = 0; i <= (n - m); i++)
	{
		for (j = 0; j < m; j++)
		{
			if (haystack[i + j] != needle[j])
				break;
		}
		if (j == m)
			return i;
	}
	return -1;
}

void test()
{
	string s1 = "mississippi";
	string s2 = "issip";
	cout << "\n主串:" << s1 << endl << "模式串:" << s2 << endl << endl;
	cout << "模式串在主串中出现的第一个位置:" << strStr(s1, s2) << endl << endl;
}

int main()
{
	test();
	system("pause");
	return 0;
}

2.1.3 运行结果

在这里插入图片描述

2.2 方法2 ~ 利用KMP算法

2.2.1 思路

Knuth–Morris–Pratt(KMP)算法是一种改进的字符串匹配算法,它的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。有关KMP的内容,推荐两个网址(网址1 、 网址2),有需要者可自行点击查看!此处不作过多解释~

而在该题中主要是利用KMP算法减少字符串的匹配次数,提高程序运行效率。

2.2.2 程序代码

#include<iostream>
#include<string>
#include<vector>
using namespace std;

/* 方法2 ~ KMP算法的代码1 */
//vector<int> GetNext(const string& str)
//{
//	vector<int> next(str.size());
//	int j = 0, k = -1;
//	next[0] = k;	
//	while (j<(str.size()-1))
//	{
//		if (k == -1 || str[j] == str[k])
//		{
//			++j;
//			++k;
//			next[j] = k;
//		}
//		else
//			k = next[k];
//	}
//	return next;
//}
//
//int strStr(string haystack, string needle) 
//{
//	vector<int> next = GetNext(needle);
//	int n = haystack.size(), i = 0;
//	int m = needle.size(), j = 0;
//	if (m <= 0)
//		return 0;
//	while (i < n && j < m)
//	{
//		if (0>j || haystack[i] == needle[j])
//			i++, j++;
//		else
//			j = next[j];
//		if (j == m )
//			return i - j;
//	}
//	return -1;
//}

/* KMP算法的代码2 */
int strStr(string haystack, string needle) {
	int n = haystack.size(), m = needle.size();
	if (m == 0) {
		return 0;
	}
	vector<int> pi(m);
	for (int i = 1, j = 0; i < m; i++) {
		while (j > 0 && needle[i] != needle[j]) {
			j = pi[j - 1];
		}
		if (needle[i] == needle[j]) {
			j++;
		}
		pi[i] = j;
	}
	for (int i = 0, j = 0; i < n; i++) {
		while (j > 0 && haystack[i] != needle[j]) {
			j = pi[j - 1];
		}
		if (haystack[i] == needle[j]) {
			j++;
		}
		if (j == m) {
			return i - m + 1;
		}
	}
	return -1;
}

void test()
{
	string s1 = "mississippi";
	string s2 = "issip";
	cout << "\n主串:" << s1 << endl << "模式串:" << s2 << endl << endl;
	cout << "模式串在主串中出现的第一个位置:" << strStr(s1, s2) << endl << endl;
}

int main()
{
	test();
	system("pause");
	return 0;
}

:上述程序中提供了两种基于KMP算法的求解代码,第一个冗杂,第二个简洁,若有想了解第二个代码,可点击此处进行具体分析!

2.2.3 运行结果

在这里插入图片描述

3、总结

本篇博客中的题目,最主要是用来练习KMP算法的,然后基于方法的多元性,又配上了一个简单的求解方法进行对比,读者可根据自己需求进行选择!只不过相比之下更推荐KMP算法!

举报

相关推荐

作文以记之 ~ 目标和

作文以记之 ~ 寻找峰值

作文以记之 ~ 岛屿数量

作文以记之 ~ 单词接龙

作文以记之 ~ 奇偶链表

作文以记之 ~ 克隆图

0 条评论