LC28.FindtheIndexoftheFirstOccurrenceinaString
题目
给你两个字符串haystack和needle,如果haystack的字串能匹配needle,返回第haystack第一个字串的开始位置,否则返回-1
题解
#include <iostream>
#include <string>
#include <vector>
//方法1
class Solution_1
{
public:
int strStr(std::string haystack, std::string needle)
{
for (int i = 0; i + needle.size() < haystack.size(); ++i)
{
bool flag = true;
for (int j = 0; j < needle.size(); ++j)
{
if (haystack[i + j] != needle[j])
{
flag = false;
break;
}
}
if (flag) return i;
}
return -1;
}
};
//方法2
class Solution_2
{
public:
int strStr(std::string haystack, std::string needle)
{
return haystack.find(needle);
}
};
//方法3
//KMP(Knuth-Morris-Pratt)算法
//用于在一个文本串中快速查找一个模式串是否出现,以及出现的位置。
//它的核心优点是避免了重复比较,时间复杂度是O(n + m) n为文本长度,m为模式串长度
//KMP算法的核心思想
//当我们在文本中匹配到一部分字符后,如果遇到了不匹配的字符,KMP利用“已经匹配的信息”来避免回溯文本指针
//KMP不像朴素匹配那样一旦失配就把文本指针回退,KMP通过“部分匹配表(next数组)”来决定模式串该往后跳多少
class Solution_3
{
public:
int strStr(std::string haystack, std::string needle)
{
if (needle.size() == 0) return 0;
std::vector<int> next = computeNext(needle);
int j = 0;
for (int i = 0; i < haystack.size(); ++i)
{
while (j > 0 && haystack[i] != needle[j])
j = next[j - 1];
if (haystack[i] == needle[j]) ++j;
if (j == needle.size()) return i - needle.size() + 1;
}
return -1;
}
private:
std::vector<int> computeNext(const std::string& pattern)
{
std::vector<int> next(pattern.size(), 0);
int j = 0;
for (int i = 1; i < pattern.size(); ++i)
{
while (j > 0 && pattern[i] != pattern[j])
j = next[j - 1];
if (pattern[i] == pattern[j]) ++j;
next[i] = j;
}
return next;
}
};
int main()
{
Solution_3 s;
std::string haystack = "abcabacababcabababa";
std::string needle = "ababa";
s.strStr(haystack, needle);
return 0;
}