串的模式匹配

时间:2022-09-09 08:37:37

(1)、Brute-Force

  暴风(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。BF算法是一种蛮力算法。

  如目标串:"caatcat",t="cat",pos=1,匹配过程如图

串的模式匹配

 程序如下:

#include<stdio.h>
#include<stdlib.h>
#define MAXNUM 100
//顺序串的存储结构,即串中的字符被依次存放在一组连续的存储单元中
typedef struct St
{
char *ch;//存放串的起始地址,串中的第i个元素存储在ch[i-1]中
int length; //串的长度
int strsize;//分配给串的存储空间大小,若不够,通过realloc()再分配,增加存储空间
}String;

String CreateNullString()
{
String s;
s.ch=(char *)malloc(MAXNUM*sizeof(char));//初始化串的存储空间
s.length=0;
s.strsize=MAXNUM;
return s;
}

//为字符串赋值
void Stringassign(String *s,char s2[])
{
int i=0;
//统计串s2的长度,若不够,然后再通过realloc去增加存储空间
while(s2[i]!='\0')
i++;

if(i>s->strsize)
{
s->ch=(char *)realloc(s->ch,i*sizeof(char));
s->strsize=i;
}

s->length=i;
for(i=0;i<s->length;i++)
s->ch[i]=s2[i];

}

/*
s:目标字符串
t:匹配字符串
pos:索引
*/
int index(String s,String t,int pos)
{
int i,j;
if(pos<1 || s.length<pos || s.length-t.length+1<pos)
{
printf("输入参数不合理\n");
exit(0);
}
i=pos-1;
j=0;
while(i<s.length && j<t.length)
{
if(s.ch[i]==t.ch[j])
{
i++;//第i个字符相等,继续匹配
j++;
}
else
{
i=i-j+1;//匹配失败,初始i的后一个位置继续开始匹配
j=0;
}
}
if(j>=t.length)
return i-t.length+1;//匹配成功,返回第匹配成功的字符串的起始地址
else
return 0;//未匹配成功

}

void main()
{
String s,t;
int i;
char ch[MAXNUM];
s=CreateNullString();
t=CreateNullString();
printf("请输入主字符串:");
gets(ch);
Stringassign(&s,ch);
printf("输入子串:");
gets(ch);
Stringassign(&t,ch);
printf("输入匹配的起始地址:");
scanf("%d",&i);
i=index(s,t,i);
printf("%d\n",i);
}

运行结果如下:

串的模式匹配

 备注:关于get()和scanf()函数的区别

gets() : gets从标准输入设备读字符串函数。可以无限读取,不会判断上限,以回车结束读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。(从stdio流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串。)

scanf() :它是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中。(从标准输入流stdio (标准输入设备,一般指向键盘)中读内容的通用子程序,可以说明的格式读入多个字符,并保存在对应地址的变量中。)

总结:

  scanf( )函数和gets( )函数都可用于输入字符串,但在功能上有区别gets可以接收空格;而scanf遇到空格、回车和Tab键都会认为输入结束,所以它不能接收空格。

1.scanf()

所在头文件:stdio.h

语法:scanf("格式控制字符串",变量地址列表);

接受字符串时:scanf("%s",字符数组名或指针);

2.gets()

所在头文件:stdio.h

语法:gets(字符数组名或指针);

3、两者在接受字符串时:

1.不同点:

scanf不能接受空格、制表符Tab、回车等;

而gets能够接受空格、制表符Tab和回车等;

2.相同点:

字符串接受结束后自动加'\0'。


 

(2)、KMP算法