#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define CHUNKSIZE 100
#define N 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2//(1)创建一个串;(2)实现BF模式匹配算法;(3)实现KMP模式匹配算法;(4)调用创建串函数创建主串和模式串;(5)调用BF算法输出匹配结果;(6)调用KMP算法输出匹配结果;
typedef char ElemType;
typedef int Status;
typedef struct {
char *ch;//若是非空串,则按串长分配存储区,否则ch 为NULL;
int length;//串的当前长度
}HString;
//初始化
Status InitHString(HString &S)//
{
S.ch = new ElemType[CHUNKSIZE];//为串分配一个数组空间
if (!S.ch)exit(OVERFLOW);//存储分配失败
// s.ch[1]="\0"或者#;//表示字符串结束标志
S.length = 0;//初始长度为0
return OK;
} //创建串
Status CreateHString(HString &S, int len)//初始化改变S
{
char e;
cout << "请输入字符串" << endl;
for (int i = 1; i<=len; i++)//循环输入字符
{
cin >> e;
S.ch[i]=e;//把字符赋值给数组
}
S.length = len;//串的当前位置
return OK;
}
Status Display(HString &S)//不用加& 没有改变串只是打印
{
for (int i = 1; i<=S.length; i++)//循环输出数组里所有内容
{
printf("%c", S.ch[i]);
}
printf("\n"); //system("cls")清屏 功能
return OK;
}
int get_next(HString T, int next[])//求模式串T的next函数值并存入数组next
{
int i = 1; next[1] = 0; int j = 0;//数组从1开始,j代表后缀末尾的下标
while (i<T.length)
{
if (j == 0 || T.ch[i] == T.ch[j])
{
++i; ++j; next[i] = j;//++后才是要得到的值
}
else j = next[j];//匹配失败进行回溯
}
}
int get_nextval(HString T, int nextval[])//让 nextval[i] = nextval[j]
{
int i = 1; nextval[1] = 0; int j = 0;//初值
while (i<T.length)
{
if (j == 0 || T.ch[i] == T.ch[j])
{
++i; ++j;
if (T.ch[i] != T.ch[j]) nextval[i] = j;
else nextval[i] = nextval[j];//相等了无需比较,进行回溯
}
else j = nextval[j];//匹配失败,回溯
}
}
//实现BF模式匹配算法
int Index_BF(HString S, HString T, int &pos)//返回模式串T在主串S中的第pos个字符开始第一次出现的位置,若不存在返回值为0
{
int i = 1; int j = 1;//初始化
while (i<=S.length &&j<=T.length)//两个串均未比较到串尾
{
if (S.ch[i] == T.ch[j])// 继续比较后续字符
{
++i;
++j;
}
else//指针后退重新开始匹配
{
i = i - j + 2;
j = 1;
}
}
if (j>T.length) //匹配成功
{
pos=i-T.length;
return i-T.length;
}
else return 0;//匹配失败
}
//实现KMP模式匹配算法
int Index_KMP(HString S, HString T, int &pos1,int next[] )//利用模式串T的next函数求T在主串S中第pos个字符之后的位置
{
int i = 1; int j = 1;
while (i <= S.length &&j <= T.length)//两个串均未比较到串尾
{
if (j == 0 || S.ch[i] == T.ch[j])// 继续比较后续字符
{
++i; ++j;
}
else j = next[j];//模式串向右移动
}
if (j>T.length) //匹配成功
{
pos1=i-T.length ;
return i - T.length;
}
else return 0;//匹配失败
}
int main()
{
int a,pos, next[N];
HString S;
InitHString(S);
printf("主串长为:");
scanf("%d", &a);
CreateHString(S, a);
printf("串S为:");
Display(S);
HString T;
InitHString(T);
printf("\n模式串长为:");
scanf("%d", &a);
CreateHString(T, a);
printf("\n串T为:");
Display(T);
Index_BF(S, T, pos);
printf("BF T在S中第 %d个字符开始匹配\n", pos);
get_next(T,next);
int pos2=Index_KMP(S, T, pos2, next);
printf("KMP T在S中第 %d个字符开始匹配\n ", pos2);
get_nextval(T, next);
int pos1=Index_KMP(S, T, pos1, next);
printf("KMP T在S中第 %d个字符开始匹配\n", pos1);
system("pause");
return 0;
}