题目描述
给定两个字符串str和match,长度分别为N和M。实现一个算法,如果字符串str中含有子串match,则返回match在str中的开始位置,不含有则返回-1
若出现了多次,则按照升序输出所有出现位置
[要求]
时间复杂度为O(n)O(n)
输入描述:
第一行一个字符串str
第二行一个字符串match
输出描述:
输出若干个数,分别为match在str中出现的位置,从0开始标号。
若不存在输出-1
示例1
输入
复制
acbc
bc
输出
复制
2
示例2
输入
复制
acbc
bcc
输出
复制
-1
示例3
输入
复制
ababab
ab
输出
复制
0 2 4
备注:
1 \leqslant length(str), length(match) \leqslant 5 * 10^51⩽length(str),length(match)⩽5∗10
5
保证字符集为小写字母
#include<bits/stdc++.h>
using namespace std;
int Next[5 * 100007];
vector<int> ans;//储存下标
string s1,s2;
void getnext(string s)
{
int j = -1;
Next[0] = -1;
for (int i = 1;i<s.length();i++)
{
while(s[i]!=s[j+1]&&j!=-1)
j = Next[j];
if(s[j+1]==s[i])
j++;
Next[i] = j;
}
}
void kmp(string s1,string s2)
{
getnext(s2);
int n = s1.length(), m = s2.length(),j=-1;
for (int i = 0;i<n;i++)
{
while(s1[i]!=s2[j+1]&&j!=-1)
j = Next[j];
if(s1[i]==s2[j+1])
j++;
if(j==m-1)
ans.push_back(i+1-m), j = -1;
}
}
int main()
{
cin >> s1 >> s2;
kmp(s1, s2);
if(ans.size()==0)
cout << -1<<endl;
else{
for (int i = 0;i<ans.size();i++)
cout << ans[i] << " ";
cout<<endl;
}
return 0;
}