前言

最近工作中需要写一个算法,而写完这个算法我却发现了一个很有意思的事情。需要的这个算法是这样的:对于A,B两个字符串,找出最多K个公共子串,使得这K个子串长度和最大。百度之没有这样的算法,然后就开始想了一些乱七八糟的想法,一一被自己举反例推翻了,直到最后找到了正确算法,我觉得这个思考过程值得记录一下。

思考过程

错误想法1:每次找最长公共子串,找到一个子串后,从A,B两个字符串中删除这个子串,之后在剩下的串中再找最长公共子串,像这样找K次。

举个反例:

A=KABCDELMABCDEFGNFGHIJK

B=KABCDEFGHIJK

K=2

按照这种方式选取结果为:ABCDEFG+HIJK,总长度为7+4=11,但是最优解为:KABCDE+FGHIJK总长度为6+6=12。

错误想法2:求A与B的最长公共子序列,之后从子序列中挑取最长的K段。

举个反例:

A=EFGIJABC

B=ABCEFHIJ

K=1

按照这种方式选取,首先求出最长公共子序列EF-IJ,取出其中最长一段长度为2。而最优解为:ABC,长度为3。

正确解法:动态规划

上面两个看似取巧但是不对的想法被推翻后,也能让我静下心来进行系统性的思考了,正确解法为动态规划。动态规划最重要的事情有三件:找问题的状态,找转移方程边界初始化。找对状态就相当于成功了一半,找到转移方程基本问题就算解了,边界初始化可以忽略不计。找状态除了靠灵感之外,我最喜欢的方法是分解问题,找到问题的最原子的状态,之后搭积木般的组合拼装就OK了。

设dp[i][j][k]表示为以A[i],B[j]为第K个公共子串结尾时,所能得到的最大值。其中A[i]为字符串A第i个字符,B[j]为字符串B的第j个字符。

在考虑A[i]和B[j]时,如果A[i] = B[j],那么A[i],B[j]可以单独组成第K个串,也可以和A[i-1],B[j-1]组合在一起作为第K个串,则转移方程如下:

dp[i][j][k] = dp[i-1][j-1][k] + 1             (与A[i-1],B[j-1]连在一起)

dp[i][j][k] = max(dp[i'][j'][k-1] + 1)      (A[i],B[j]单独成为第K个串)

当单独成串时,需要遍历所有i',j',如果我们能在计算dp[i][j][k]的时候顺便记录截止到当前选取k个串时的最大值的话,就可以避免遍历,所以最后的状态以及转移方程如下:

dp[i][j][k] = max(dp[i-1][j-1][k] + 1, maxscore[i-1][j-1][k-1] + 1)

maxscore[i][j][k] = max(maxscore[i-1][j][k],maxscore[i][j-1][k], dp[i][j][k])

现在回头看一下这个算法,当K=1的时候就是最长公共子串问题,当K=min(length(A), length(B))的时候就是最长公共子序列问题,想想还是挺有意思是的。

结语

对于一个棘手的问题,可能一开始想不到正确的算法,我们这时可以尽可能的把能想到的解法全都考虑一遍,该推翻的推翻,该证明的证明,在推翻和证明的过程中更深刻的理解这个问题,最终找到正确的答案。
 

一个自己研究出来的字符串匹配算法-k子串算法的更多相关文章

  1. 字符串匹配算法之 kmp算法 (python版)

    字符串匹配算法之 kmp算法 (python版) 1.什么是KMP算法 KMP是三位大牛:D.E.Knuth.J.H.MorriT和V.R.Pratt同时发现的.其中第一位就是<计算机程序设计艺 ...

  2. 字符串匹配算法之BM算法

    BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法. BM算法定义了两个规则: ...

  3. 字符串匹配算法之Sunday算法(转)

    字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...

  4. 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!

    前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...

  5. 字符串匹配算法:Sunday算法

    背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...

  6. 字符串匹配算法之Sunday算法

    字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...

  7. 字符串匹配算法之————KMP算法

    上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符.但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位: 关于KMP算法的描述,推荐一篇博 ...

  8. 字符串匹配算法之kmp算法

    kmp算法是一种效率非常高的字符串匹配算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,所以简称KMP算法 算法思想 在一个字符串中查找另一个字符串时,会遇到如下图的情况 我们通常 ...

  9. 字符串匹配算法(二)-BM算法详解

    我们在字符串匹配算法(一)学习了BF算法和RK算法,那有没更加高效的字符串匹配算法呢.我们今天就来聊一聊BM算法. BM算法 我们把模式串和主串的匹配过程,可以看做是固定主串,然后模式串不断在往后滑动 ...

随机推荐

  1. es6 总结知识点

    1. let  和 const 只在代码块中有效  {}   js块级作用域. const 定义的对象是可以改变其属性的 const a =[], b={} ; a.push(1); b.a=1; / ...

  2. 初学python之路-day08前期总结

    # 1# 计算机原理:控制器 运算器 存储器 input设备 output设备 IO流# 三大核心:CPU 内存 硬盘 # 内存分布:栈区 与 堆区# 如二进制与十进制的转换,如1111转成十进制为1 ...

  3. P2444 [POI2000]病毒

    P2444 [POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已 ...

  4. php 获取用户的IP、地址、来源

    js方法获取用户的 ip 和 地址 <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> ...

  5. 同时安装多个的Mysql的实现方法

    首写修改my.ini文件 修改这几项即可 [client] port= [mysql] default-character-set=utf8 [mysqld] port= server_id= 全文如 ...

  6. CF1082

    D 乱搞题..发现只有a[i]=1是特殊的 瞎搞一下 E 发现一段的贡献是出现次数最多的-为c个数 然后考虑分别对每种颜色做一下 然后每次只有这种颜色和他们之间是有用的 然后做个最大区间和就好了 F ...

  7. Netty5服务端源码解析

    Netty5源码解析 今天让我来总结下netty5的服务端代码. 服务端(ServerBootstrap) 示例代码如下: import io.netty.bootstrap.ServerBootst ...

  8. Kafka文件存储机制及partition和offset

    转载自:  https://yq.aliyun.com/ziliao/65771 参考:  Kafka集群partition replication默认自动分配分析    如何为kafka选择合适的p ...

  9. mongDB数据库 小白学习

    一  安装配置 1.配置文件mongod.cfg (路径:D:\data\config\mongod.cfg) 如下: systemLog: destination: file path: D:\da ...

  10. resume

    源码链接(码云):https://gitee.com/tinqiao/level_17_software_engineering.git 截图效果: 源码: <!DOCTYPE html> ...