第4章学习小结_串(BF&KMP算法)、数组(三元组)

时间:2022-01-29 07:35:16

  这一章学习之后,我想对串这个部分写一下我的总结体会。

  串也有顺序和链式两种存储结构,但大多采用顺序存储结构比较方便。字符串定义可以用字符数组比如:char c[10];也可以用C++中定义一个字符串string a;这就需要根据具体场景来选择合适方便操作的方法。还有空串和空格串是不同的,空串字符长度为0(符号‘),空格串包含一个或多个空格。这一章学习了两个串的模式匹配算法,特别是KMP算法,从中受益匪浅。

一、串

1、BF(Brute-Force)算法

  这个模式匹配算法简单直观,被人们称为暴力算法。它就是将模式串跟主串从开头一个一个比较,如果匹配失败,又从模式串第二个字符一次比较,以此类推,逻辑思维不高,所以简单,容易理解,现在用途还很大。

       i 0 1 2 3 4
主串 a b c a b
模式串j(第1次比较) c a b    
          (第2次比较)   c a b  
          (第3次比较)     c a b

这里我是用字符串下标,从0开始,可以看出每次比较模式串都从j=0开始,而i就是上次初始比较的下一个就是i=i-j+1,比如上面的第一次比较后i=0,j=0;下一次i=0-0+1,即从i=1进行匹配。

现在以题目为例,写一下我的解题过程。

7-1 串的模式匹配 

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

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

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

输入样例:

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

aaaaaba
ba

输出样例:

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

int BF(string A,string B)//这里算法是从下标为0开始,所以跟书里有点不同
{
int i=,j=;
while(i<A.length()&&j<B.length())
{
if(A[i]==B[j])
{
++i;++j;
}
else
{
i=i-j+;j=;//根据上面分析,下标后退进行比较
}
}
if(j>=B.length()) return i-j+; //返回匹配成功第一个位置
return ;
}

我感觉用下标比较容易操作,只需要改一下相应的位置,然后直接用C++定义字符串string,再输入字符串,相对也比较简洁。

主函数如下:

int main()
{
string a,b;
getline(cin,a);//输入一个串之后回车就可以输入下一个串
getline(cin,b);
//int num=BF(a,b);
//int num=KMP(a,b);这里两个选一个,下面KMP算法的主函数一样
cout<<num;
return ;
}

这道题用BF算法可以简单就解决了,那为啥还要有KMP算法呢?

  一般情况下,BF算法时间复杂度为O(m*n),数据量不大时候,执行时间近似为O(m+n),但如果是庞大数据,那它的效率就很低了,我们老师专门设了一个测试点主串长度100万,模式长度10万,而且是那种主串为aaaaaaaa...,模式串是ba......。所以,从第一个字符比较一直不匹配,而模式串一直回溯到j=0,这样工作量超大,所以上面BF算法提交之后在这个测试点是运行超时的。

这样,才有优化算法KMP,第一次看的时候一脸懵,无法理解三个大牛的逻辑思维。所以我搜索了几篇博客认真学习,试图融入大牛的思维世界。

(链接:https://blog.csdn.net/henuyx/article/details/44653799https://www.cnblogs.com/tangzhengyue/p/4315393.html

2、KMP算法

这种改进算法是由D.E.Knuth、J.H.Morris、V.R.Pratt三位大牛同时设计实现的。下面我就捋一下我入门的思路方法。

  KMP最让人难以理解就是它的next数组是如何得到的,开始我觉得很神奇,next数组居然实现了字符匹配的“跳转”。举个例子,看看是如何算出next数组的。

模式串  a b a a b c a c


下标 j  0 1 2 3 4 5 6 7


next[j] -1 0 0 1 1 2 0 1

先算一下每个字符的最长相等前后缀吧

  前缀 后缀 最长相等前后缀
a 0
ab a b 0
aba a,ab a,ba 1
abaa a,ab,aba a,aa,baa 1
abaab a,ab,aba,abaa b,ab,aab,baab 2
abaabc a,ab,aba,abaa,abaab c,bc,abc,aabc,baabc, 0
abaabca a,ab,aba,abaa.abaab,abaabc a,ca,bca,abca,aabca,baabca 1
abaabcac a,ab,aba,abaa,abaab,abaabc,abaabca c,ac,cac,bcac,abcac,aabcac,baabcac 0

经过观察,每个字符对应next数组的值为其前面的字符的最长相等前后缀,然后因为时按下标比较,将next[0]=-1;所以现在给出任意一个模式串,都可以很快确定它的next数组值。如:a b c d a b d, next[j]={-1,0,0,0,0,1,2}。现在就上计算next值的算法:

int* getnext(string T)  //定义指针函数getnext(),求模式串T的next函数值并放入next数组
{
int* next = new int[T.length()]; //动态申请模式串T存储空间
int Tl = T.length();
int i = ; // T的下标
int j = -; //因为是按下标比较,所以 j = -1,next[0] = -1;
next[] = -;
while(i<Tl)//T串未比较到串尾
{
if(j==-||T[i]==T[j])//若字符匹配,或者j==-1,则进行下一个字符比较,并求出T[i]字符对应的next值
{ //T[i]是后缀,T[j]是前缀
++i;++j;next[i]=j;
}
else j=next[j];//若字符不匹配,求出字符对应的next值
}
return next;//因为是指针函数 ,所以返回next数组首地址 }

刚开始,根据书里的代码实现不了将next传到KMP函数体里面,查了相关资料,可以通过指针函数将数组传过去,其实是返回数组首地址。

  KMP算法函数:

int KMP(string S,string T)//KMP算法
{
int i=,j=;
int sl=S.length();
int tl=T.length();
int *next=getnext(T);//用next指针接受指针函数传来的数组地址 while(i<sl&&j<tl)
{
if(j==-||S[i]==T[j])//如果j = -1,或者当前字符匹配成功(即S[i] == P[j])
{
++i;++j;
}
else
{
j=next[j];//next[j]即为j所对应的next值
}
}
if(j>=tl) return i-j+;//匹配成功,返回第一次匹配位置
else return ;//匹配失败,返回0
}

这道题我从理解到完成用了差不多1天时间,大部分时间花费在理解算法上面,特别是“跳转”的next数组,感觉既神奇又有趣。而PTA的这道题经过几次debug,主要是细节错误导致开始运行结果错误。就这样,要通过最后一个测试点然后学到了KMP算法思想,还是挺好的。

二、数组

主要学习是特殊矩阵的压缩存储,节省空间,放入新的数组,还有稀疏矩阵,用三元组表来表示,而十字链表就比较难了。三元组定义:

typedef struct{
int i,j,value; //行下标i,列下标j,值value
}node;//三元组 typedef struct{
int m,n,nzero;//矩阵行数m,矩阵列数n,非零个数nzero
node a[];//三元组数组
}Matrix;//三元组表

PTA上面用这个方法就很简单解决

现在存在的问题就是,写代码能力不高,思路虽然比较清晰,但是再转化为代码时候需要花较多时间,上次小测也是这样,因为写代码量不够,最后做题时间不够,最后一道简单的题目没来得及做,所以,以后需要花时间读写代码,这样才能做得更好。谢谢您的阅读!

第4章学习小结_串(BF&KMP算法)、数组(三元组)的更多相关文章

  1. 数据结构学习之字符串匹配算法&lpar;BF&vert;&vert;KMP&rpar;

    数据结构学习之字符串匹配算法(BF||KMP) 0x1 实验目的 ​ 通过实验深入了解字符串常用的匹配算法(BF暴力匹配.KMP.优化KMP算法)思想. 0x2 实验要求 ​ 编写出BF暴力匹配.KM ...

  2. 数据结构之BF算法,kmp算法,三元组,十字链表总结

    在这一章中,老师教了我们四种数据结构:BF算法,kmp算法,三元组和十字链表:还给我们讲了2019年团体天体赛中T1-8的AI题 1.对于BF和kmp算法,老师除了在课堂上讲解算法的主要核心思想外,还 ...

  3. hdu 3336&colon;Count the string(数据结构,串,KMP算法)

    Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. 串的两种模式匹配方式(BF&sol;KMP算法)

    前言 串,又称作字符串,它是由0个或者多个字符所组成的有限序列,串同样可以采用顺序存储和链式存储两种方式进行存储,在主串中查找定位子串问题(模式匹配)是串中最重要的操作之一,而不同的算法实现有着不同的 ...

  5. 数据结构与算法JavaScript &lpar;五&rpar; 串&lpar;经典KMP算法&rpar;

    KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配 ...

  6. 常用算法3 - 字符串查找&sol;模式匹配算法(BF &amp&semi; KMP算法)

    相信我们都有在linux下查找文本内容的经历,比如当我们使用vim查找文本文件中的某个字或者某段话时,Linux很快做出反应并给出相应结果,特别方便快捷! 那么,我们有木有想过linux是如何在浩如烟 ...

  7. 第3章:LeetCode--算法:strStr KMP算法

    https://leetcode.com/problems/implement-strstr/  28. Implement strStr() 暴力算法: int ViolentMatch(char* ...

  8. 20181117-python第二章学习小结-part2

    浮点型补充: 有限小数与无限循环小数,不包括无理数! 小数点后面的数据运算太复杂,精确度不及整数! 尽量使用科学计数表示小数 列表学习(语法) 创建:[] list = []  #创建空表 list ...

  9. 20181115 python-第一章学习小结part4

    python第一章 流程控制 单分枝任务 If  条件: 满足条件执行动作 注意if下面的缩进,建议直接使用tab键,4个空格太难输入. 双分枝任务 If  条件: 满足条件执行动作 else: 条件 ...

随机推荐

  1. 用WinForm写的员工考勤项目!!!!!!

    先说几句,作为一个还在学习的程序员,掌握的知识有限:但我利用自身所学,给一些像我一样还在学习的码农提供我的绵薄之力! 写的不好,但是尽力了,希望大牛指点.多多吐槽!!! 好了开始说项目需求: 实现新增 ...

  2. bzoj 1458 网络流

    我们可以知道每行最多可以有多少个格子不用建点,设为x[i],每列同理设为y[i],那么我们连接(source,i,x[i]),(i,sink,y[i])表示我们将一个格子不建点,那么(i,j,flag ...

  3. Codeforces Round &num;308 &lpar;Div&period; 2&rpar;B&period; Vanya and Books 数学

    B. Vanya and Books Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/552/pr ...

  4. SRM470 - SRM474&lpar;1-250pt&comma;500pt&rpar;&lpar;471-500pt为最短路&comma;474-500pt未做&rpar;

    SRM 470 DIV1 250pt 题意:有n个房间排成一排,相邻两个房间之间有一扇关闭着的门(共n-1扇),每个门上都标有‘A’-‘P’的大写字母.给定一个数n,表示第n个房间.有两个人John和 ...

  5. CEPH RGW 设置 user default&lowbar;placement为ssd-placement,优化100KB-200KB小文件性能,使用户创建的bucket对象放置到 SSD设备的Pool上。

    sudo radosgw-admin metadata get user:tuanzi > user.md.json vi user.md.json #to add ssd-placement ...

  6. 初学Java Web&lpar;9&rpar;——学生管理系统(简易版)总结

    项目开始时间:2018年4月8日14:37:47 项目完成时间:2018年4月9日10:03:30 技术准备 这个项目是自己用于巩固 J2EE 相关知识的练手项目,非常简单,但是相关的功能却非常实用, ...

  7. &lt&semi;&lt&semi;精通iOS开发&gt&semi;&gt&semi;第14章例子代码小缺陷的修复

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 首先推荐大家看这本书,整本书逻辑非常清晰,代码如何从无到有,到 ...

  8. day10(闭包、import模块、函数命名空间)

    #闭包:嵌套函数,内部函数调用外部函数的变量 # def outer(): # a = 1 # def inner(): # print(a) # inner() # outer() def oute ...

  9. Pollard Rho大质数分解学习笔记

    目录 问题 流程 代码 生日悖论 end 问题 给定n,要求对n质因数分解 普通的试除法已经不能应用于大整数了,我们需要更快的算法 流程 大概就是找出\(n=c*d\) 如果\(c\)是素数,结束,不 ...

  10. jQuery插件初级练习5

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...