我们如何使用动态编程解决子字符串匹配检查

Posted

技术标签:

【中文标题】我们如何使用动态编程解决子字符串匹配检查【英文标题】:How can we solve substring matching check using Dynamic Programming 【发布时间】:2014-11-19 18:39:00 【问题描述】:

我学习了使用动态编程查找最长公共子串的程序。我们也可以使用动态规划来找出字符串中是否存在子字符串吗?

我试过了。但是,这似乎使事情变得更加复杂!

下面是我尝试过的伪代码。

字符串:你好

子字符串:llo

f(n) : 如果未找到子字符串的字符或找到的位置,则返回 false

f(0) = 匹配索引或错误

f(1) = f(0) 索引的下一个索引是 substring[1] 或 false

f(2) = f(1) 索引的下一个索引是 substring[1] 或 false

f(n) = f(n-1) 后跟当前字符的下一个索引或 false

调用:substring('hello', 2, 'el');

substring(str, n, substring)

        if(n == 0)
        
                for(i=0;i<strlen(str);i++)
                
                        if(str[i] == substring[n])
                                pos[] = i; //append i to positions array
                
                if(pos) return pos;
                return false;
        
        else
        
                indexes = substring(str, n-1, substring);
                if(indexes)
                
                        foreach(indexes as index)
                        
                                if(str[index+1] == substring[n])
                                        return true;
                        
                        return false;
                
        


【问题讨论】:

这是一个递归定义:“函数f(needle, haystack)通过在needle == haystack(1:length(needle))f(needle, haystack(2:end))中返回true来确定子字符串needle是否出现在更大的字符串干草堆中”现在应用DP。 所以您发布的伪代码类似于您的真实代码。请发布编译时没有错误和警告的真实代码 - 除非是编译器错误让你感到困惑。 “我学会了使用动态规划寻找最长公共子串的程序。我们也可以使用动态规划来找出字符串中是否存在子串吗?” 你怎么可能做到前者不能做后者? falsetruepos 是不同的类型。 【参考方案1】:

我认为你不能用 DP 解决这个问题。

例如,假设您有一个句子 S 和单词 W。您想检查给定的单词 W 是否是句子 S 的子字符串。只有 LCS(最长公共子字符串)的长度才可以使用 DP等于单词W的长度,这意味着W实际上就是那个LCS。复杂度为 O(N * M),其中 N 是 S 的长度,M 是 W 的长度。

使用 KMP、O(N + M) 或散列可以做得更好。

【讨论】:

以上是关于我们如何使用动态编程解决子字符串匹配检查的主要内容,如果未能解决你的问题,请参考以下文章

动态规划:字符串匹配

检查字符串是不是包含子字符串。此外,获取索引和匹配数(Raku)

检查字符串是不是包含子字符串列表并保存匹配的子字符串

用正则表达批量快速解决如“过滤注释的//”“查询特定单词”“匹配特定子字符串”等工作中难题

javascript 检查String是否包含多个子字符串匹配

RegEx - 匹配以冒号开头的子字符串