从键盘输入一个目标串S,并输入要匹配的模式串T,利用串的简单的模式匹配和KMP算法,定位模式串在主串中的位置。
设计要求:
首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
主控菜单设计要求:
程序运行后,显示一个标题“模式匹配算法”,标题下方给出6个菜单项的内容和输入提示:
- 输入一个主串S
- 输入一个模式串T
- 输入模式串T的next函数值(计算模式串T的next函数值,并按格式显示出next函数 值)
- 实现简单模式匹配
- 实现KMP模式匹配
- 继续/否(y/n?)
请选择1--6:
功能要求:
完成各菜单的功能;
菜单2,计算后要按格式显示出next函数值;
菜单3、4,要求实现在主串的第pos个位置开始,实现模式匹配。完成后要将主串、模式串及匹配的情况显示出来
实现要求:用串的定长顺序存储
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//串的定长顺序存储结构
#define MAXLEN 255
typedef struct
{
char ch[MAXLEN+1];
int length;
}SString;
//BF算法,模式串T在主串S中第pos个字符开始第一次出现的位置
int Index_BF(SString S,SString T,int pos)
{
int i=pos;
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 )
{
printf("匹配成功!\n");
printf("主串为:%s\n",S.ch);
printf("模式串为:%s\n",T.ch);
printf("模式串在主串第%d个字符开始第一次出现的位置为:%d\n",pos,i-T.length);
return (i-T.length);
}
else
{
printf("匹配失败!\n");
printf("主串为:%s\n",S.ch);
printf("模式串为:%s\n",T.ch);
return 0;
}
}
//计算next函数值
void get_next(SString T,int next[])
{
int i=1,j=0;
next[1] = 0;
while(i < T.length)
{
if(j==0 || T.ch[i] == T.ch[j])
{
++i;
++j;
next[i]=j;
}
else
j=next[j];
}
}
//KMP算法
int Index_KMP(SString S,SString T,int pos)
{
int i=pos;
int j=1;
int next[255];
get_next(T,next);
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)
{
printf("匹配成功!\n");
printf("主串为:%s\n",S.ch);
printf("模式串为:%s\n",T.ch);
printf("模式串在主串第%d个字符开始第一次出现的位置为:%d\n",pos,i-T.length);
return i-T.length;
}
else
{
printf("匹配失败!\n");
printf("主串为:%s\n",S.ch);
printf("模式串为:%s\n",T.ch);
return 0;
}
}
//主函数
int main()
{
SString S;
SString T;
int next[MAXLEN+1];
int choice,pos,pos1,q=1,i,j=1;
char c;
printf("***************模式匹配算法***************\n");
printf("1.输入一个主串S\n");
printf("2.输入一个模式串T\n");
printf("3.输入模式串T的next函数值(计算模式串T的next函数值,并按格式显示出next函数值)\n");
printf("4.实现简单模式匹配\n");
printf("5.实现KMP模式匹配\n");
printf("6.继续/否?(y/n?)\n");
while(choice)
{
printf("请选择操作1--6:\n");
scanf("%d",&choice);
if(choice>6||choice<=0)
{
printf("您输入的数据有误!\n");
return 0;
}
while(choice<=6)
{
if(choice==1)
{
printf("请输入一个主串(以#开头):\n");
scanf("%s",S.ch);
S.length=strlen(S.ch)-1;
break;
}
if(choice==2)
{
printf("请输入一个模式串(以#开头):\n");
scanf("%s",T.ch);
T.length=strlen(T.ch)-1;
break;
}
if(choice==3)
{
printf("求模式串的next函数值\n");
get_next(T,next);
printf("j 的值为: ");
for(j=1;j<=T.length ;j++)
printf("\t%d\t",j);
printf("\n模式串的值为:");
for(i=1;i<=T.length ;i++)
printf("\t%c\t",T.ch[i]);
printf("\n串的next值为:");
for(q=1;q<=T.length;q++)
printf("\t%d\t",next[q]);
printf("\n");
break;
}
if(choice == 4)
{
printf("实现简单模式匹配:\n");
printf("请输入pos值:\n");
scanf("%d",&pos);
Index_BF(S,T,pos);
break;
}
if(choice==5)
{
printf("实现KMP模式匹配:\n");
printf("请输入pos1值:\n");
scanf("%d",&pos1);
Index_KMP(S,T,pos1);
break;
}
if(choice==6)
{
printf("请输入y/n选择继续或退出\n");
getchar();
scanf("%c",&c);
if(c=='y')
{
printf("请输入操作1--6继续运行程序:\n");
scanf("%d",&choice);
}
if(c=='n')
{
printf("操作完成,退出程序!\n");
return 0;
}
}
}
}
return 0;
}