ADT




模式匹配(问题描述)



模式匹配(蛮力匹配)





KMP算法(记忆法)




KMP算法(查询表)





问题:
应该是这样吧:next[]数组只与模式串有关,是一个int数组,数组长度与模式串的长度相同,描述了模式串的某样特征。

int []next = buildNext§;
构造next数组时,第一位next[0] = -1,用作某种标志位,next数组中除第一位的值都是数组的某个秩,值的大小不会超过next.length,为0表示无法匹配,为正整数表示可以跳转匹配

这种特征或许是模式串内部前后的相似,如果模式串是一个所有字符都互不相同的字符串,那么next[]数组主体就都为0了啊,(by haiyesensi )
答:理解正确。对于字符集较大的情况,KMP 没有优势。(by yuantailing 老师)

KMP算法(理解next[]表)




-1处配置一个假想的通配符*,可以匹配任意字符,j<0,表示与任意字符都相等,即与T[i] == T[j] 逻辑相同

KMP算法(构造next[]表)

有next数组的性质知,以红线分开的两部分相等,即前缀等于后缀,如果P[j] == p[next[j]] 则next数组的值可以增加1


引用自KMP算法的Next数组详解




问题:
构造next[]表而失配时,为何选择 P[n(n(j))] 而不是其他(by D不发音 )
答:如果 P[n[n[j]]] == P[j],是可以得出 P[0, n[n[j]] + 1) == P[j - n[n[j]], j + 1) 的。因为 P[j] 前面有 n[j] 长度的前缀匹配,P[n[j]] 前面又有 n[n[j]] 长度的前缀匹配,所以前面 n[n[j]] 个字符等于 P[n[j]] 前面的 n[n[j]] 个字符,从而等于 P[j] 前面的 n[n[j]] 个字符。严格从式子推导如下:

对于 P[j],由 next 表的定义知 P[0, n[j]) == P[j - n[j], j),(1)
对于 P[n[j]],由 next 表的定义知 P[0, n[n[j]]) == P[n[j] - n[n[j]], n[j]) (就是把上式中的 j 全换成 n[j])(2)
由(1)式得等号两边的子串相等:P[n[j] - n[n[j]], n[j]) == P[j - n[n[j]], j),(3)
由(2)(3)得 P[0, n[n[j]]) == P[j - n[n[j]], j),(4)
所以 P[0, n[n[j]] + 1) == P[j - n[n[j]], j + 1)。(5)(by yuantailing 老师)

KMP算法(分摊分析)



KMP算法(再改进)


不能以卵击石,确定0与1不相配后,我们不能犯相同的错误,一直以鸡蛋0与石头1相配



问题:
优化后还更慢?
我去做了HDU-1711 http://acm.hdu.edu.cn/showproblem.php?pid=1711 我优化后的代码还慢了100ms左右,不说了,直接上优化后的代码

#include
#include
using namespace std;

int cas;
int N, M;//M:b N:a
int b[10000], a[1000000];
int Next[10000];

void getNext()
{
int t = Next[0] = -1;
int j = 0;
while (j < M - 1)
{
if (t < 0 || b[j] == b[t])
{
j++;
t++;
Next[j] = b[t] == b[j] ? Next[t] : t;
}
else
t = Next[t];
}
}

int KMP()
{
int i = 0, j = 0;
getNext();
while (i < N && j < M)
{
if (j < 0 || a[i] == b[j])
{
i++;
j++;
}
else
j = Next[j];
}
if (j == M)
return i - j + 1;
else
return -1;
}

int main()
{
ios::sync_with_stdio(false);
cin >> cas;
while (cas–)
{
cin >> N >> M;//a:N b:M
for (int i = 0; i < N; ++i)
cin >> a[i];
for (int i = 0; i < M; ++i)
cin >> b[i];
cout << KMP() << endl;
}

return 0;

}(by duck145879)
答:改进的 next[] 表与不改进的 next[] 表相比,计算 next[] 表本身的时间慢一点,但 KMP 匹配的时候跳转的平均长度稍大一点。

构造后一个 next[] 表只用一次体现不出优势。如果一个模式串要与很多个字符串匹配, 改进的 next[] 构造时间微不足道,匹配的速度就体现出来了。(by yuantailing 老师)

BM算法:BC策略(以终为始)






问题:
直观上从前开始还是从后开始应该对称的,为什么实际上效率却不一样。(by dave20081996)
答:
如果文本串的首字母未在模式串中出现,我们只能将文本串向后移动一位;

而如果文本串第L个字母(假设L是模式串长度)在模式串中未出现,那么我们就知道,文本串以1到L为开头的所有子串,都不可能和模式串一致,因为该子串中包含了一个未在模式串中出现过的串,从而可以移动整整L步。(by ydc123 老师)
问:
平均不足一次?
老师提到采用以始为终的策略后,平均每个字符的比对次数会小于1,这是否是因为这里的比对次数并没有计入为了确认当前文本串中的字符不在模式串中所需要的比对次数而所导致的的错误结论呢?比如为了确认“道”并不在“非常名”里所需要的比对次数。(by alex-sun123 )
答;
“确认当前文本串中的字符不在模式串中”可以O(1)实现,比如hash表、位图(by ydc123 老师)

BM算法:BC策略(坏字符)






问;
为何不选用在P[j]左侧并与之最近的那个X?
pdf文档中的描述如下:

即使‘X’在P中出现,但最右侧者过于靠右(以至于位移量为负)呢?

对于此种情况的处理方法是将P[]右移一个字符,那为何…不选用在P[j]左侧并与之最近的那个X?

到底是为什么呢?可否举出反例?(by liucongvg17 )
答:
用左侧最近的 X 也是正确的。

但是,学完后面几节后会知道,BC 策略只为字母表里的每个字母记录了一个数,表示最右侧的位置。因此,对于任意位置 j 和字母 X,求“j 左侧最近的 X”在现有框架下是做不到的,需要“现算”,或者记录一个数组表示 X 的所有出现位置再二分查找。(by yuantailing 老师)

算法:BC策略(构造bc[])


BM算法:BC策略(性能分析)


BM算法:GS策略(好后缀)





BM算法:GS策略(构造gs表)







BM算法:GS策略(综合性能)





Karp-Rabin算法(串即是数)




问:将一组向量转换成数值(采用素数的平方)之后,怎么进行还原,忘各位大侠指点!(by ∑379397 )
答:设计算出的自然数为 U,向量维度n,前n个素数记为{xi},对应次幂为{ai}

思路:用xi除U,能除出几个,ai值就为几,当前xi除不出来,换下一个

初始化 i=0 ai=0
while(U>1)
if U%xi ==0 ai++;U/=xi;
else i++
(by 嗷呜55555)
把U质因数分解,素数幂次-1就是向量该位置的数。比如75600= 24 ×33×52×7 ,那么还原回来的数组就是{3,2,1,0}(by 易笑天)

问:字符串和对应d进制自然数不是单射?
老师你好,请问这个是从什么角度考量出来的,每个字母视作当前数位上的一个数字,那么对应的数不应该是独一无二的?(by 骑马督战官)
答:fine,fine…忘了0前缀的重复问题。(by 骑马督战官)

Karp-Rabin算法(散列)




邓俊辉 数据结构 串相关推荐

  1. 清华大学邓俊辉-数据结构MOOC笔记-树的概念及逻辑表示

    清华大学邓俊辉-数据结构MOOC笔记-树的概念及逻辑表示 有关概念: 与图论略有不同,数据结构中的树:1.需要为每一颗树指定一个特殊的顶点,作为"根"(root),对应rooted ...

  2. 邓俊辉数据结构学习心得系列——如何正确衡量一个算法的好坏

    数据结构这门课主要关注如何设计合理的数据结构和算法,来简化时间复杂度和空间复杂度. 想要科学的解决这样一个优化的问题,最核心的思想也是最基础的,就是要量化问题.这也是将数学运用在实际问题中的一个基石. ...

  3. 邓俊辉数据结构学习心得系列——数据结构中所研究的算法

    写在前面的话: 本文只是个人学习邓俊辉老师C++数据结构的整理,包含了很多个人的见解(从内容到材料的组织形式).所整理的内容不保证逻辑性和完整性,仅供参考. 算法的基本性质: 有正确的输入 有正确的输 ...

  4. 邓俊辉数据结构学习-3-栈

    栈的学习 栈的应用场合 逆序输出 输出次序与处理过程颠倒,递归深度和输出长度不易预知 不是很理解 实例:进制转换 大致思路:对于进制转换,我们一般使用的都是长除法,因此要保存每次得到的余数,但是最后算 ...

  5. 邓俊辉 数据结构与算法C++版 第十三章 串 ADT

    邓公数据结构与算法 第十三章 串 ADT 定义和特点 术语 ADT接口实现 模式匹配 问题与需求 算法测试方法 蛮力匹配 构思 蛮力匹配:版本1 蛮力匹配:版本2 蛮力匹配:性能分析 KMP算法 ne ...

  6. 邓俊辉数据结构学习-7-BST

    二叉搜索树(Binary-Search-Tree)--BST 要求:AVL树是BBST的一个种类,继承自BST,对于AVL树,不做太多掌握要求 四种旋转,旋转是BBST自平衡的基本,变换,主要掌握旋转 ...

  7. 邓俊辉数据结构学习笔记3-二叉树

    二叉树及其表示 树 有根树 从图论的角度看,树等价于连通无环图.因此与一般的图相同,树也由一组项点〈vertex)以及联接与其间的若干条边〈edge) 组成.在计算机科学中,往往还会在此基础上,再指定 ...

  8. 邓俊辉数据结构学习笔记2

    列表 typedef int Rank; //秩 #define ListNodePosi(T) ListNode<T>* //列表节点位置template<typename T&g ...

  9. 邓俊辉数据结构与算法学习笔记-第十一章

    文章目录 11.串 11.a ADT 11.b 串匹配 11.b1 串匹配 11.b2 蛮力匹配 11.c KMP算法 11.c1 KMP算法:从记忆力到预知力 11.c2 KMP算法查表 11.c3 ...

最新文章

  1. python 语言教程(3)变量之列表(List)
  2. 浙江大数据交易中心正式上线
  3. 调用GPU进行神经网络的训练 GPU环境的搭建
  4. 2019CCPC江西省赛
  5. corosynclib+drbd+mysql组合应用
  6. 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
  7. IncDec Sequence(差分)
  8. MariaDB忘记root密码
  9. 新版quartus_prime破解与altera官网下载器件库
  10. 在win10pe中集成virtio驱动
  11. 蔡学镛谈Java学习
  12. c语言中合法整型常量负号,C语言中整型常量的表示方法
  13. 企鹅F4手机外观设计有突破 配MTK6592八核处理器
  14. 怎样修心?不乱于心,不困于情。
  15. 【程序人生】领导素质 | 第 5 级领导力:个人谦逊和坚定意志的胜利 | Level 5 Leadership: The Triumph of Humility and Fierce Resolve
  16. ps保存psd后图层全没了_明明只有几个图层,为什么我的 PSD 文件这么大?
  17. three.js快速入门和实战
  18. Python概述:C++程序员眼中的Python
  19. align-content 和align-items的区别
  20. R_Studio(学生成绩)对数据缺失值md.pattern()、异常值分析(箱线图)

热门文章

  1. VC数据库编程总结(二)
  2. LeetCode #1087. Brace Expansion
  3. 最佳实践:千巡翼Q30+机载LiDAR在水域三维数据采集中的应用
  4. 2020-04-06-B站学习视频
  5. Machine Learning Summary
  6. 分享|契约锁电子档案产品,组织的数字化成果永久封存、可查可验
  7. Python实现哈里斯鹰优化算法(HHO)优化卷积神经网络分类模型(CNN分类算法)项目实战
  8. oracle授权表的权限给某个用户
  9. iOS蓝牙打印价签:【商品条码、品名、零售价、规格信息等】(商品名称支持换行显示)
  10. 基于BCompare数据比对