题目描述
给你两个字符串,一个S,一个T,现在请你判断一下能否从字符串S种找到字符串T? 如果可以的话,请输出S中T的起始位置,如果不能请输出-1
输入
题目有多组测试样例,
每组第一行输入字符串S
第二行输入字符串T
题目保证字符串中没有空格
输出
输出S中T的起始位置,不存在请输出-1
如果有多种答案,请输出第一次出现的起始位置
样例输入 Copy
abaacababcac
ababc
abc
d
样例输出 Copy
6
-1
思路
- 寻找前缀后缀最长公共元素长度(prefix_table)
- 将求出的长度数组右移一位(move_prefix_table)
- 将数组与字符串进行匹配(kmp_search)
AC代码
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
char text[100005];
char str[1000005];
int nums[100005];
int n,m;
void prefix_table(){
nums[0]=0;
int i=1,len=0;
while(i<m){
if(str[i]==str[len]){
len++;
nums[i]=len;
i++;
}else{
if(len>0){
len=nums[len-1];
}else{
nums[i]=len;
i++;
}
}
}
}
void move_frefix_table(){
for(int i=m-1;i>0;i--){
nums[i]=nums[i-1];
}
nums[0]=-1;
}
void kmp_search(){
prefix_table();
move_frefix_table();
int i=0,j=0,flag=0;
while(i<n){
if(j==m-1&&text[i]==str[j]){
flag=1;
break;
}
if(j==-1||text[i]==str[j]){
i++;
j++;
}else{
j=nums[j];
}
}
if(flag==0){
cout<<-1<<endl;
}else{
cout<<i-j+1<<endl;
}
}
int main(){
while(cin>>text>>str){
n=strlen(text);
m=strlen(str);
kmp_search();
}
return 0;
}