第五次作业:串的模式匹配

这个作业属于哪个课程 https://edu.cnblogs.com/campus/qdu/DS2020
这个作业要求在哪里 https://edu.cnblogs.com/campus/qdu/DS2020/homework/11392
这个作业的目标 串的概念、串的模式匹配算法的实现
学号 2018204261

实验四:串的匹配模式

一、实验目的

1、了解串的基本概念
2、掌握串的模式匹配算法的实现

二、实验预习

说明以下概念
1、模式匹配:模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配。

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

3、KMP算法:KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)

三、实验内容和要求

1、阅读并运行下面程序,根据输入写出运行结果。

#include<stdio.h>
#include<string.h>

#define MAXSIZE 100

typedef struct{
	char data[MAXSIZE];
	int length;
}SqString;

int strCompare(SqString *s1,SqString *s2);/*串的比较*/
void show_strCompare();
void strSub(SqString *s,int start,int sublen,SqString *sub);/*求子串*/
void show_subString();

int strCompare(SqString *s1,SqString *s2){
	int i;
	for(i=0;i<s1->length&&i<s2->length;i++)
	if(s1->data[i]!=s2->data[i])
	return s1->data[i]-s2->data[i];
	return s1->length-s2->length;
}

void show_strCompare(){
	SqString s1,s2;
	int k;
	printf("\n***show Compare***\n");
	printf("input string s1:");           
    gets(s1.data);
	s1.length=strlen(s1.data);
	printf("input string s2:");
	gets(s2.data);
	s1.length=strlen(s2.data);
	if(k=strCompare(&s1,&s2)==0)
	    printf("s1=s2\n");
	else if(k<0)
	    printf("s1<s2\n");
	else
	    printf("s1>s2\n");
	printf("\n***show over***\n"); 
}

void strSub(SqString *s,int start,int sublen,SqString *sub){
	int i;
	if(start<1||start>s->length||sublen>s->length-start+1)
	{
		sub->length=0;
	}
	for(i=0;i<sublen;i++)
		sub->data[i]=s->data[start+i-1];
		sub->length=sublen;
}

void show_subString(){
	SqString s,sub;
	int start,sublen,i;
	printf("\n***show subString***\n");
	printf("input string s:");
	gets(s.data);
	s.length=strlen(s.data);    
	printf("input start:");
	scanf("%d",&start);
	printf("input sublen:");
	scanf("%d",&sublen);
	strSub(&s,start,sublen,&sub);
	if(sub.length==0)
	    printf("ERROR!\n");
	else
	{
		printf("subString is:");
		for(i=0;i<sublen;i++)
		    printf("%c",sub.data[i]);
	}
	printf("\n***show over***\n");
}

int main(){
	int n;
	do{
		printf("\n--String--\n");
		printf("1.strCompare\n");
		printf("2.subString\n");
		printf("0.EXIT\n");
		printf("\ninput choice:\n");
		scanf("%d",&n);
		getchar();
		switch(n){
			case 1:show_strCompare();break;
			case 2:show_subString();break;
			default:n=0;break;
		}
	}
	while(n);
	return 0;
}

·运行程序
输入:
1
student
students
2
Computer Data Stuctures
10
4
运行结果:

2、实现串的模式匹配算法。补充下面程序,实现串的BF和KMP算法。

#include<stdio.h>
#include<string.h>

#define MAXSIZE 100

typedef struct{
	char data[MAXSIZE];
	int length;
}SqString;

int index_bf(SqString *s,SqString *t,int start);
void getNext(SqString *t,int next[]);
int index_kmp(SqString *s,SqString *t,int start,int next[]);
void show_index();

int index_bf(SqString *s,SqString *t,int start){
	int i,j,pos;
	if(t->length==0)
	return(0);
	pos=start;
	i=pos;
	j=0;
	while(i<s->length&&j<t->length)
	if(s->data[i]==t->data[j])
	{
		i++;j++;
	}
	else
	{
		pos++;
		i=pos;
		j=0;
	}
	if(j>t->length)
	return(pos);
	else
	return(-1);
}

void getNext(SqString *t,int next[]){
	int i=0,j=-1;
	next[0]=-1;
	while(i<t->length)
	{
		if(j==-1||(t->data[i]==t->data[j]))
		{
			i++;
			j++;
			next[i]=j;
		}
		else
		j=next[j];
	}
}

int index_kmp(SqString *s,SqString *t,int start,int next[]){
	int i,j;
	if(t->length=0)
	return(0);
	while(i<s->length&&j<t->length)
	if(s->data[i]==t->data[j])
	{
		i++;j++;
	}
	else
	j=next[j];
	if(j>=t->length)
	return(i-j);
	else
	return(-1);
}

void show_index(){
	SqString s,t;
	int k,next[MAXSIZE]={0},i;
	printf("\n***show index***\n");
	printf("input string s:");
	gets(s.data);
	s.length=strlen(s.data);
	printf("input string t:");
	gets(t.data);
	t.length=strlen(s.data);
	printf("input start position:");
	scanf("%d",&k);
	printf("BF:\nthe result of BF is %d\n",index_bf(&s,&t,k));
	getNext(&t,next);
	printf("KMP:\n");
	printf("next[]:");
	for(i=0,i<t.length;i++;)     
	    printf("%3d",next[i]);
	printf("\n");
	printf("the result of KMP is %d\n",index_kmp(&s,&t,k,next));
	printf("\n***show over***\n");     
}

int main(){
	show_index();
	return 0;
}

输入:
abcaabbabcabaacbacba
abcabaa
1

运行结果:

四、实验小结

1、BF算法是直接的,是我们在解决模式匹配问题时较为直观的想法,没有过多的技巧,比较目标串的第一个字符和模式串的第一个字符,相同就比较目标串的第二个字符和模式串的第二个字符,不相同就比较目标串的第一个字符与模式串的第二个字符,直到相同为止。
2、KMP算法是基于BF算法改进的,在我们演示BF算法的过程中,我们会发现,存在着无用功的情况,我们并没有充分利用已知的信息,所以我们引入了前缀、后缀的概念,同时又定义了Next【i】,用它来表示第i个位置相同的最长前缀和后缀的长度。如果第i个位置匹配不成功,同过Next【i】,我们可以确定目标串移动的位数。

posted @ 2020-10-30 11:05  山海志  阅读(434)  评论(0编辑  收藏  举报