c++练习三:找出字符串中第一个匹配项的下标
今天的题目是:
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
实现
这次的题目本人想到了两种解法 一种 是暴力破解法 一种是直接调用string中的find api 官方还给出了第三种解法 KMP 算法(Knuth-Morris-Pratt 算法)。
- 暴力破解法
首先枚举 haystack 中的每个字符作为起点,每次从haystack的起点和needle的首位开始匹配:
- 匹配成功:返回本次匹配的haystack起点。
- 匹配失败:枚举haystack的下一个起点」,重新尝试匹配。
- 调用api
这种方法没什么好说的直接用封装好的find方法就行 - kmp
kmp目前还没吃透 等吃透了在回来更新思路
实现代码
实现一
这里摘抄了官方代码
class Solution {
public:
int strStr(string haystack, string needle) {
int n = haystack.size(), m = needle.size();
for (int i = 0; i + m <= n; i++) {
bool flag = true;
for (int j = 0; j < m; j++) {
if (haystack[i + j] != needle[j]) {
flag = false;
break;
}
}
if (flag) {
return i;
}
}
return -1;
}
};
实现二
class Solution {
public:
int strStr(string haystack, string needle) {
return haystack.find(needle);
}
};
实现三
这里摘抄了官方代码
class Solution {
public:
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;
}
};