#include<iostream>
#include<stdio.h>
#include<string>
#include"structfun.h"
using std::string;
using std::printf;
using std::scanf;
using std::endl;
using std::to_string;
int main()
{
//KMP模式匹配算法
//1、定义两个字符数组S1(主串),S2(查找子串)
//2、求出S2的next数值
//3、根据next数值匹配S1主串
#define MAXSIZE 100
char S1[MAXSIZE];
char S2[MAXSIZE];
int next[MAXSIZE];
printf("输入主串S1:");
cin>>S1;
printf("输入子串S2:");
cin>>S2;
//求S2的next值
//例:S2=abdabg
// next[0]=0; next[1]=1 a next[2] =1 a ab; next[3]=1 a ab abd
// next[4]=2 a=a ab abd abda; 一个重复
// next[5]=3 a=a ab=ab abd abda abdab两个重复
// 既next[0]=0 next[i]=1+(i的字符前缀和后缀相等字符串的长度) next[5]就是“ab”的长度加1既是3
//采用两个循环计算next值
//next[0]=0;
//next[1]=1;
//从第三个值开始计算,前两个位0、1
//int i=2,n=1;
//while(S2[i]!=0)
//{
// //提取前端跟后端的字符串相比a ab abd abda abdab
// int bf,af;
// bf=1;
// af=i;
// string bs,as;
// for(int j=1;j<af;j++)
// {
// bs=bs+S2[j-1];
// as=S2[af-j]+as;
// if(bs==as)
// {
// n=bs.length()+1;
// }
// }
// next[i]=n;
// i++;
//}
//****还是需要两个循环**还是有回溯 不好
//改进 分析ababaaabad
// 0 next[0]
//a 1 next[1]
//a b s[0]!=s[1] 1 next[2]
//aba s[0]=s[2] 2 next[3]
//abab s[1]=s[3] 3 next[4]
//ababa s[2]=s[4] 4 next[5]
//ababaa s[3]!=s[5] 2 next[6]回溯到上次不相等
//ababaaa s[1]!=s[6] 2 next[7]回溯到上次不想等
//ababaaab s[1]=s[7] 3 next[8]
//ababaaaba s[2]=s[8] 4 next[9]
next[0]=0;
next[1]=1;
int i=1,k=1,nb=0;
while(S2[i+1]!=0)
{
if(S2[nb]!=S2[i])//不相等回溯
{
if(nb==0)
k=1;
else
k=next[nb];
}
else
{
k++;
nb++;
}
//KMP改进,加判断前缀的前一个和后缀的后一个是否相等,相等则直接next[i+1]=前缀的前一个
if(S2[i+1]==S2[nb])
next[i+1]=next[nb];
else
next[i+1]=k;
i++;
}
//与主字符串进行比较。一个循环遍历主字符串
int f1=0,f2=0;
string str;
str=S2;
while(S1[f1]!=0)
{
if(S1[f1]==S2[f2])
{
f1++;
f2++;
}else
{
if(next[f2]==0)
f1++;
else
f2=next[f2]-1;
}
if (S2[f2]==0)
{
printf("找到了,在%d位置\n",f1-str.length()+1);
//f1++;
f2=0;
}
}
system("pause");
}
字符串KMP模式匹配算法
最新推荐文章于 2024-04-14 17:48:07 发布