第一种 string的find()函数
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
string s1, s2;
string::size_type position;
//find 函数 返回s2 在s1 中的下标位置
while(cin >> s1 >> s2){
position = s1.find(s2);
if (position != s1.npos) //如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295,
{
printf("%d\n",position+1);//下标从0开始
}
else
{
printf("-1\n");
}
}
return 0;
}
第二种kmp算法
#include <iostream>
#include <cstring>
using namespace std;
char text[1000005];
char str[1000005];
int nums[1000005];
int n,m;
//求出匹配字符串的前缀表 str
//next数组
void prefix_table(){
nums[0] = 0;
// i当前最后一个字符
int i = 1;
int 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_prefix_table(){
for(int i = m - 1 ; i > 0 ; i --){
nums[i] = nums[i - 1];
}
nums[0] = -1;
}
// KMP搜索算法
void kmp_search(){
prefix_table();
move_prefix_table();
int i,j;
i = j = 0;
while (i < n){
if(j == m - 1 && text[i] == str[j]){
printf("%d\n", i - j + 1);
//如果是要继续匹配下去的
j = nums[j];
// break;
//如果不要继续匹配直接break
}
//匹配成功
if(j == - 1 || text[i] == str[j]){
i ++;
j ++;
}else{
j = nums[j];
}
}
}
int main()
{
while(scanf("%s %s",text,str) != EOF){
n = strlen(text);
m = strlen(str);
kmp_search();
}
return 0;
}
改良后的kmp
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<math.h>
#include<string.h>
#include<sstream>
using namespace std;
int num[10005];
int n, m;
string str1,str2;
void prefix_table(){
num[0] = -1;
int i = 0, j = -1;
while(i < n){
if(j == -1 || str1[i] == str1[j]){
i ++;
j ++;
num[i] = j;
} else {
j = num[j];
}
}
}
int kmp_search(){
int cnt = 0;
int i = 0, j = 0;
while(j < m){
if(i == -1 || str1[i] == str2[j]){
i ++;
j ++;
} else {
i = num[i];
}
if(i == n){
cnt ++;
}
}
return cnt;
}
int main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while(t --){
memset(num,0,sizeof(num));
cin >> str1 >> str2;
n = str1.size();
m = str2.size();
prefix_table();
cout << kmp_search() << endl;
}
return 0;
}