一个自己研究出来的字符串匹配算法-k子串算法
前言
最近工作中需要写一个算法,而写完这个算法我却发现了一个很有意思的事情。需要的这个算法是这样的:对于A,B两个字符串,找出最多K个公共子串,使得这K个子串长度和最大。百度之没有这样的算法,然后就开始想了一些乱七八糟的想法,一一被自己举反例推翻了,直到最后找到了正确算法,我觉得这个思考过程值得记录一下。
思考过程
错误想法1:每次找最长公共子串,找到一个子串后,从A,B两个字符串中删除这个子串,之后在剩下的串中再找最长公共子串,像这样找K次。
举个反例:
A=KABCDELMABCDEFGNFGHIJK
B=KABCDEFGHIJK
K=2
错误想法2:求A与B的最长公共子序列,之后从子序列中挑取最长的K段。
举个反例:
A=EFGIJABC
B=ABCEFHIJ
K=1
正确解法:动态规划
上面两个看似取巧但是不对的想法被推翻后,也能让我静下心来进行系统性的思考了,正确解法为动态规划。动态规划最重要的事情有三件:找问题的状态,找转移方程,边界初始化。找对状态就相当于成功了一半,找到转移方程基本问题就算解了,边界初始化可以忽略不计。找状态除了靠灵感之外,我最喜欢的方法是分解问题,找到问题的最原子的状态,之后搭积木般的组合拼装就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个串)
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])
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?