给出两个字符串S1&不同长度的S2,找到S1和S2的最后一个字符匹配的S1和S2的相等子序列数的有效方法是什么。
e.g)
S1 = ayb
S2 = axbxxb
在这种情况下,存在两个相等的子序列,
"b" => S1[2],S2[2]
"b" => S1[2],S2[5]
"ab" => S1[0],S2[0] and S1[2],S2[2]
"ab" => S1[0],S2[0] and S1[2],S2[5]
我知道这可以通过动态编程来解决,如果有人提出有效地解决这个问题的想法会很棒。
答案 0 :(得分:0)
这基本上是正则表达式匹配问题。
首先让我们摆脱“最后一个角色匹配”的条件。我们希望将问题简化为“平等数量的相等子序列问题,没有任何条件。”
假设S1 =“a 1 a 2 ... a n Z”。设S1'=“a 1 a 2 ... a n ”。假设S2中还有N次出现Z.对于每次出现,我们都可以写
假设S2中有N次出现Z.对于每次出现 i ,我们可以写出S2 i =“b 1 b 2 ... b ķ<子> I 子> 子> ZB <子>ķ<子> I 子> 1 子> ...“。假设S2'=“b 1 b 2 ... b k i ”。现在为1'N中的每个i解决S1'和S2' i 的普通问题。
现在,如何解决普通问题?
拿一根较短的绳子,说是S1。我们现在写它"abc…t"
。将其转换为".*a?.*b?.*…t?.*"
。这是你的正则表达式。您现在需要计算正则表达式与S2匹配的方式。匹配可以使用基于NFA的算法完成。
要实际计算匹配数,需要了解基于NFA的匹配算法的内部工作原理。在任何给定时刻都有一组活跃的状态。一个州可以分成两个,或两个州可以合并。如果遇到错误的角色,州就会死亡。因此,您将分数1指定为初始状态。当状态分裂时,每个新状态都会继承父级的分数。当两个州合并时,新州获得分数的总和。当一个州死亡时,其分数就会下降。
我不确定这与你所谓的动态编程方法有什么不同。最多有2个 N 匹配,因此在某些输入上,此将需要很长时间。
更新:看起来应该也可以直接解决“最后一个字符匹配”问题,而不会将其简化为普通问题。假设在S2中出现2次Z:S2 =“ab ... pZq ... yZ”。 (无论如何,可以忽略最后一个Z之后的所有字符)。可以用S2构建一个正则表达式:".*a?.*b?.*…p?.*(Z|Z?.*q?.*…y?.*Z)"
。更多事件以相同的方式处理。一个看似多余的正则表达式需要保持正确的匹配数量(而不仅仅是匹配的事实)。