《数据结构》实验报告四:串的模式匹配(BF算法、KMP算法)
一、实验目的
1、了解串的基本概念。
2、掌握串的模式匹配算法的实现 。
二、实验预习
说明以下概念
1、模式匹配:
串的模式匹配就是子串的定位运算。
设有两个字符串 S 和 T ,S为主串(正文串),T为子串(模式串)。在主串S中查找与模式串T相匹配的子串,若匹配成功,确定相匹配的子串中的第一个字符主串S中出现的位置。
2、BF算法:
即暴力破解算法(Brute Force),属于模式匹配算法中的一种。
算法思想:从主串和模式串的第一个字符开始比较,匹配成功则进行下一字符的比较;匹配失败则主串比较的字符回溯到初始比较字符的下一位,而模式串比较的字符回溯到模式串第一个字符,接着继续进行字符比较。
3、KMP算法:
KMP算法也属于模式匹配算法的一种,是一种改进后的匹配算法。
KMP算法的改进在于当出现字符不匹配时,主串比较的字符无需回溯,而模式串则利用已经匹配成功的部分字符,确定模式串回溯的位置(无需回溯到第一个字符)。
KMP算法减少了模式串与主串的匹配次数,达到快速匹配的目的。
三、实验内容和要求
!注 !
本实验中的字符数组 data 从下标为0的数组分量开始存储字符串。部分教材为便于说明问题,字符串从下标为1的数组分量开始存储,下标为0的分量闲置不用,故代码略有区别。
1、阅读并运行下面程序,根据输入写出运行结果。
#include<stdio.h>
#include<string.h>
#define MAXSIZE 100 //串的最大长度typedef struct{char data[MAXSIZE]; //存储串的一维数组(从下标为0的数组分量开始存储字符串)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;/* s1=s2,返回值=0s1>s2,返回值>0s1<s2,返回值<0 */
}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);s2.length=strlen(s2.data);if((k=strCompare(&s1,&s2))==0)printf("s1=s2\n");else if(k<0)printf("s1<s2\n");elseprintf("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;else{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:");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]; //存储串的一维数组(从下标为0的数组分量开始存储字符串)int length; //串的当前长度
}SqString;int index_bf(SqString *s,SqString *t,int start); /*模式匹配-BF算法*/
void getNext(SqString *t,int next[]); /*计算目标串的next数组*/
int index_kmp(SqString *s,SqString *t,int start,int next[]); /*模式匹配-KMP算法*/
void show_index();int index_bf(SqString *s,SqString *t,int start){//补充代码
}void getNext(SqString *t,int next[]){ /*计算模式串t的next数组*/int i=0;int j=-1;next[0]=-1;while(i < t->length){if(-1==j || (t->data[i]==t->data[j])){i++;j++;next[i]=j;}elsej=next[j];}
}int index_kmp(SqString *s,SqString *t,int start,int next[]){//补充代码
}void show_index(){SqString s,t;int k;int i;int next[MAXSIZE]={0};int nextval[MAXSIZE]={0};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(t.data);printf("input start position(1≤start position≤%d):",s.length);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;
}
BF算法代码:
int index_bf(SqString *s,SqString *t,int start){ /*返回模式串t在主串s中第start个字符开始第一次出现的位置;若不存在,返回0*///模式串t长度为0 或 起始查找位置超出主串范围:直接返回0if(0 == t->length || start < 1 || start > s->length)return (0);int pos=start-1; //pos记录主串s开始匹配的字符下标int i=pos; //i指向主串s当前正待比较的字符下标int j=0; //j指向模式串t当前正待比较的字符下标while( i < s->length && j < t->length ){if(s->data[i] == t->data[j]) //匹配成功:i,j都++,继续比较后续字符{i++;j++;}else //匹配失败{pos++; //主串开始匹配的位置+1i=pos; //i回溯到主串初始位置下一字符j=0; //j回溯到模式串第一个字符}}if(j >= t->length)return (pos-start+2); //返回模式串t在主串s中第start个字符开始第一次出现的位置elsereturn (-1); //查找失败,返回-1
}/*index_bf*/
KMP算法代码:
int index_kmp(SqString *s,SqString *t,int start,int next[]){ /*返回模式串t在主串s中第start个字符开始第一次出现的位置;若不存在,返回0*///模式串t长度为0 或 起始位置超出主串范围:直接返回0if(0 == t->length || start < 1 || start > s->length)return (0);int i=start-1; //i指向主串s当前正待比较的字符下标int j=0; //j指向模式串t当前正待比较的字符下标while(i<s->length && j<t->length){if(-1 == j || (s->data[i] == t->data[j])){i++;j++;}else //匹配失败{j=next[j]; //i不回溯,j回溯到next[j]}}if(j>=t->length)return (i-j-start+2); //返回模式串t在主串s中第start个字符开始第一次出现的位置elsereturn (-1); //查找失败,返回-1
}/*index_kmp*/
输入:
abcaabbabcabaacbacba
abcabaa
1
运行结果:
3、在第2题的基础上,对next数组进行改进,实现计算目标串的nextval数组的算法,并进行验证。
nextval数组算法代码:
void getNextVAL(SqString *t,int nextval[]){ /*计算模式串t的nextval数组*/int i=0;int j=-1;nextval[0]=-1;while(i < t->length){if(-1 == j || (t->data[i]==t->data[j])){i++;j++;if(t->data[i] != t->data[j])nextval[i]=j;elsenextval[i]=nextval[j];}elsej=nextval[j];}
}/*getNextVAL*/
show_index函数补充代码:
void show_index(){SqString s,t;int k;int i;int next[MAXSIZE]={0};int nextval[MAXSIZE]={0};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(t.data);printf("input start position(1≤start position≤%d):",s.length);scanf("%d",&k);printf("BF:\nthe result of BF is %d\n",index_bf(&s,&t,k));getNext(&t,next);getNextVAL(&t,nextval);printf("KMP:\n");printf(" next[]:");for(i=0;i<t.length;i++)printf("%3d",next[i]);printf("\n");printf("nextval[]:");for(i=0;i<t.length;i++)printf("%3d",nextval[i]);printf("\n");printf("the result of KMP is %d\n",index_kmp(&s,&t,k,nextval));printf("\n***show over***\n");
}
输入:
abcaabbabcabaacbacba
abcabaa
1
运行结果:
《数据结构》实验报告四:串的模式匹配(BF算法、KMP算法)相关推荐
- 数据结构实验报告四 图的表示与遍历
一.实验目的 1.掌握图的邻接矩阵和邻接表表示 2.掌握图的深度优先和广度优先搜索方法 3.理解图的应用方法 二.实验内容和要求 1.阅读并运行下面程序,根据输入写出运行结果. #include< ...
- 北京理工大学计算机实验四报告表,北京理工大学数据结构实验报告实验四
北京理工大学数据结构实验报告实验四 (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 <数据结构与算法设计>实验报告--实 ...
- 数据结构实验报告,二叉树的基本操作(C语言)
数据结构实验报告,二叉树的基本操作(C语言) 作者:命运之光 专栏:数据结构 目录 数据结构实验报告,二叉树的基本操作(C语言) 实验六 二叉树的基本操作 一.需求分析 二.概要设计 三.详细设计 四 ...
- C语言数据结构线性表上机实验报告,数据结构实验报告实验一线性表_图文
数据结构实验报告实验一线性表_图文 更新时间:2017/2/11 1:23:00 浏览量:763 手机版 数据结构实验报告 实验名称: 实验一 线性表 学生姓名: 班 级: 班内序号: 学 号: ...
- 数据结构实验报告(六)
数据结构实验报告(六) 一.实验名称 实验六 图的实验1--图的邻接矩阵存储实现 二. 实验目的 1. 熟练理解图的相关概念: 2. 掌握图的邻接矩阵的存储方法的实现: 3. 学会图的遍历算法 ...
- [入门必看]数据结构4.2:串的模式匹配
[入门必看]数据结构4.2:串的模式匹配 第四章 串 4.2 串的模式匹配 知识总览 4.2.1_朴素模式匹配算法 4.2.2_1_KMP算法 4.2.2_2_求next数组 4.2.3_KMP算法的 ...
- 农夫过河【数据结构实验报告】
数据结构实验报告 实验名称:实验三 农夫过河 学号:*** 姓名:gnosed 实验日期:2017.10.30 一.实验目的 1.进一步掌握队列的使用 2.会使用队列进行农夫过河解的搜索 二.实验具体 ...
- 数据结构实验报告(一)
数据结构实验报告(一) 一.实验名称 实验一 线性表的基本操作实现及其应用 二.实验目的 1.熟练掌握线性表的结构特点,掌握顺序表的基本操作. 2.巩固 C++相关的程序设计方法与技术. 3.学会使 ...
- 图的遍历c语言数据结构实验报告,数据结构实验报告--图的遍历
江 西 理 工 大 学 数据结构 实验报告 实验名称 图的遍历 日期 2014-12-01 专业班级 计算机(中加)131班 地点 信息学院621 实验人 王鹏伟 学号 同组人 单独完成 152013 ...
最新文章
- 简明高效的 Java 并发编程学习指南
- 《需求工程-软件建模与分析之读书笔记之三》
- 数据包注入重放工具aireplay-ng
- python3 字符串填充 清除
- matlab-绘制分叉与混沌分支图
- 更改centos 7 的默认启动为命令界面
- 测试点分析:1048 数字加密 (20分)_16行代码AC
- 常用的数据结构_三分钟了解区块链常用数据结构「默克尔树」
- [转载]十四步实现拥有强大AI的五子棋游戏
- 工业机器人 答案 韩建海_不可或缺:协作机器人对于制造业转型升级的意义
- HTML+CSS+JS实现 ❤️酷炫的时光隧道旅行动特效❤️
- 开启中国区块链创造季! 2019区块链开发者大会来袭!(首批重磅嘉宾曝光)
- Android/Linux编译开关使用
- 刘知远老师的“灵魂发问”:关系抽取到底在乎什么?
- 用命令关闭计算机,使用DOS命令关机的操作步骤
- PlayStation@4功能介绍及测试应用
- 《帝国时代III黄金版》宣布
- 好好生活,总会遇见美好事物
- 科技交流英语(2022秋)Unit 5 test
- 机器学习算法基础(使用Python代码)