第四章学习小结

这两周上课学的较多且比较有印象的是串的模式匹配算法那道题

同时可以用BF或者KMP算法进行解决。

一开始学BF算法时就在想如何改进可以使匹配更加简便

后来KMP的学习让我对串的学习有了更深入的了解

同时BF和KMP算法之间的联系也是一个算法改进的很好学习范例

7-1 串的模式匹配

给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串S中出现的位置。

输入格式:

输入有两行: 第一行是主串S; 第二行是模式T.

输出格式:

输出相匹配的子串中的第一个字符在主串S中出现的位置。若匹配失败,输出0.

输入样例:

在这里给出一组输入。例如:

aaaaaba
ba

输出样例:

在这里给出相应的输出。例如:

6

在这道题中原本使用BF或者KMP算法都可以解决,但是老师修改了主串和模式串的长度后,使用BF算法在长度的测试点中会因为超时而无法通过,因而要通过所有测试点,只能使用KMP算法。

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 char* a(string str){
 5     int size = str.length();
 6     char *s;
 7     s= new char[size];
 8     strcpy(s, str.c_str());
 9     return s;
10 }
11 void b_next(string Pstring, int *next){
12     next[0] = -1;
13     int j = 0, k = -1;
14     int p_len = Pstring.length();
15     char *p = a(Pstring);
16     while(j<p_len){
17         if(k == -1 || p[j] == p[k]) {
18             k++;
19             j++;//k:开始前缀下标,j:后缀下标
20             next[j] = k;
21         }else{
22             k = next[k]; //k回溯
23         }
24     }
25 }
26 int kmp(string Sstring, string Pstring){
27     int *next = new int[Pstring.length()];
28     b_next(Pstring, next);//获取next[]数组
29     char *s = a(Sstring);
30     char *p = a(Pstring); //转换为字符数组
31     int i=0, j=0;
32     int pos = 0;
33     while( i<=Sstring.length() || j<=Pstring.length()){
34         if( j == -1 || s[i] == p[j]){
35             i++;
36             j++;
37         }else{
38             j = next[j];
39         }
40         if(j == Pstring.length()){
41             pos = i-j+1;
42             break;
43         }//成功匹配
44     }
45     return pos;
46 }
47 int main()
48 {
49     string Sstring, Pstring;//定义字符串
50     getline(cin, Sstring);
51     getline(cin, Pstring);//输入字符串
52     cout<<kmp(Sstring, Pstring);
53     return 0;
54 }

个人理解KMP相较于BF算法,比较特别的是next数组的获取。

next数组中,与其对应的每个字符的值为其前面字符的前后缀(最长),令next[0]=-1(下标比较)。给出任意一个模式串,即可确定它的next数组值。

e.g.

a b c d a b d, next[j]={-1,0,0,0,0,1,2}。

用next指针接受指针函数传来的数组地址
如果s【j】 == p【j】当前字成功匹配
next【j】便是j对应的next值接着返回第一次匹配位置

主串S的指针i不必回溯便可使原本BF算法的O(m*n)变为O(m+n)

学习内容中pk,pj的计算,如“设next【j】=k,则next【j+1】=?”之类的问题,在课后也是看PPT看了很久才明白

感觉这几节课学得比起往前更为充实,这两周敲代码的时间也比之前多了许多。

上课效率感觉高了很多,但是还是有待改进,比如上机老师讲题目那节课效率很差导致后面做那道题花了比别人更多的功夫。

接下来保持前几节课的效率,同时多做些编程练习,感觉自己的编写代码能力与其他优秀的同学比还有很大差距,要慢慢跟上大部队。

 

原文地址:https://www.cnblogs.com/GuanZetao/p/10705926.html

时间: 2024-09-29 04:58:18

第四章学习小结的相关文章

数据结构第四章学习小结

第四章主要是串和数组的学习,之前对串和数组的应用仅限于对其单独处理,本章学习着重于对具体题目的实际操作,实践了串的模式匹配算法,对其有了更深入的了解,数组的应用拓展到了稀疏矩阵的存储的实现. 一.串 串的模式匹配 BF算法 首先未匹配到串尾时,将两个字符串一一匹配,可用C++自带的length()函数实现 while(i<=S.length()&&j<=T.length()) 接下来就是匹配的过程 if(S[i]==T[j]){ i++;j++; }//若匹配则继续比较下一位

【数据结构】第四章学习小结

串.数组 在第四章中,我学到的主要是关于串与数组的内容,至于广义表,既然老师让我们课后有时间去看,那我这里就先不讲广义表了(其实只是粗略的看了一下,还没看懂) 在上学期的c++中我就已经学过有关串的一些知识,对于串还是可以很好的理解的,在数据结构中,串将被看作是一种特殊的线性表,跟线性表一样,串也有两种基本存储结构,个人觉得顺序存储结构对于串的运用比较方便,简单易懂,所以在作业题中会首先考虑使用顺序串. 串有许多很重要的应用,例如搜索引擎,数据压缩等,这些应用都离不开串的模式匹配算法(子串的定位

DS第四章学习小结

本章最令人印象深刻的题就是AI核心代码这题了.如下 说实话,刚看到这题真的懵了,虽然只是一道题,但总给人6题的感觉.尽管困难重重,但还是在陈晓梅老师的指导下,大致完成了此题. 逻辑分析 先定义数据结构,自然是字符数组/字符串最初考虑主函数逻辑,主要是读取输入语句,并调用接口处理输入语句并输出.基本流程是,读入一句,对其进行扫描.判断.操作,再存到新的字符串,最后输出新的字符串. 一开始输入部分就卡住了,因为不知道怎么处理回车后还能输入数据,进度就陷入了停滞,不过课上根据老师所说getchar()

第四章学习小结 串的模式匹配 解题心得体会

串的模式匹配 解题心得体会 关于串,模式匹配是其一个很重要的问题.针对这个问题,书上讲了两种模式匹配的算法,即BF算法和KMP算法,下面针对这两种算法的实现谈谈我的心得. 一.BF算法的探索 [错误代码1] #include<iostream> #include<string.h> using namespace std; typedef struct{ char ch[1000002]; int length; }SString; void Index_BF(SString S,

第四章 学习小结

我想谈谈我写模式匹配题时的心得体会: 如果是用BF算法我觉得的这道题真的非常简单,我是用的BF算法, 一开始我把string和书上的sstring搞混淆了 就像下图的代码所示: S.[i]==T.[j] S.length 但是string是头文件<cstring>包含的所以应该打成这样 S[i]==T[j] S.length() 老师上课时讲过这个,但我当时没有认真记下来,课后翻书,就直接按书上的打了,所以就出现错误.后来查阅了相关资料才修改过来了 因为用的是string所以我的BF算法函数如

第三章学习小结—-转

[学习目标] 01掌握一维数组的声明和使用方法(OK) 02掌握二维数组的声明和使用方法(OK) 03掌握字符串的声明.赋值.比较和连接方法(连接很少用) 04熟悉字符的ASCII码和ctype.h中的字符函数 05正确认识++.+=等能修改变量的运算符(OK) 06学会用编译选项-Wall获得更多的警告信息(OK) 07了解不同操作系统中换行符的表示方法(嗯) 08掌握fgetc和getchar的使用方法(fgetc基本没用过) 09掌握预处理和迭代开发的技巧(嗯) 程序3-1 逆序输出 输入

数据结构 第一章学习小结

数据结构   第一章学习小结 1.数据结构第1章的心得体会: 这周学习了数据结构的绪论及第一章.初步了解了数据结构与算法的相关概念,一开始看书看视频时觉得还挺抽象的,不能够完全理解.但是反复多看了几遍之后,结合例题,自己去操作去跑代码,慢慢觉得容易理解接受起来了.由于现在以网课形式进行教学,老师上课的同时基本还是靠自己去理解学习.当然老师也发挥很大的作用,比如让我们更深入的了解递归的空间复杂度为什么与问题规模有关,又怎样去找到该函数的临界值等等.既锻炼了我们深入思考的能力,也让我们更加清楚了解不

《Linux内核设计与实现》第四章学习笔记

第四章 进程调度 [学习时间:1小时45分 撰写博客时间:2小时10分钟] [学习内容:Linux的进程调度实现.抢占和上下文切换.与调度相关的系统调用] 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间.进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统. 最大限度利用处理器时间的原则:只要有可以执行的进程,那么总会有程序正在执行. 一.多任务 1.概念:多任务操作系统就是能同时并发地交互执行多个进程的操作系统,在单处理器机器上这会产生多个进程在同时运行的幻觉

构建之法第四章学习心得

今天我学习了构建之法第四章,主要讲述了两人合作的理论和知识点.合作,无论在任何领域,都是不可缺失的,往往能产生不可替代的效果.同样在软件设计中也是如此,经过我的学习,我了解到软件设计中两人合作主要包括包括代码规范.极限编程.结对编两人合作的不同阶段以及影响他人的技巧. 其中最让我印象深刻的是代码规范.包括:代码风格规范和代码设计规范,代码风格规范主要是文字上的规定,看似表面文章,实际上非常重要:代码设计规范牵涉到程序设计.模块之间的关系.设计模式.等方方面面的通行原则: 同时,我了解了代码风格规