【问题标题】:Number of equal subsequences of two strings S1 and S2 with the last char of S1 matched两个字符串 S1 和 S2 与 S1 的最后一个字符匹配的相等子序列的数量
【发布时间】:2012-04-11 08:19:09
【问题描述】:

给定两个不同长度的字符串 S1 和 S2,找到 S1 和 S2 的相等子序列的数量与 S1 的最后一个字符匹配的有效方法是什么。

例如)

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]

我知道这可以使用动态编程来解决,如果有人提出有效解决这个问题的想法会很棒。

【问题讨论】:

  • 我不认为这被称为“子序列”编辑:忽略我,这是一个子序列
  • @Argote 那么什么是“子序列”?

标签: string algorithm dynamic-programming


【解决方案1】:

这基本上是一个正则表达式匹配问题。

首先让我们摆脱“最后一个字符匹配”的条件。我们希望将问题简化为“无条件的等子序列的简单数量问题。

假设 S1="a1a2...anZ"。令 S1'="a1a2...an"。进一步假设在 S2 中有 N 次出现 Z。对于每一次出现,我们都可以写

假设在 S2 中有 N 次出现 Z。对于每次出现 i 我们可以写 S2i="b1b2...b kiZbki+1..."。假设 S2'="b1b2...bki"。现在解决 S1' 和 S2'i 的简单问题,对于 1..N 中的每个 i。

现在,如何解决简单的问题?

取较短的字符串,假设它是 S1。现在让我们把它写成"abc…t"。将其转换为".*a?.*b?.*…t?.*"。这是你的正则表达式。您现在需要计算正则表达式匹配 S2 的方式有多少。可以使用基于 NFA 的算法进行匹配。

要实际计算匹配数,需要了解基于 NFA 的匹配算法的内部工作原理。在任何给定时刻都有一组处于活动状态的状态。一个状态可以一分为二,或者两个状态可以合并。如果遇到错误的字符,状态可能会死亡。因此,您将 1 分分配给初始状态。当一个状态分裂时,每个新状态都会继承父级的分数。当两个状态合并时,新状态得到分数的总和。当一个国家死亡时,它的分数就会下降。

我不确定这与您所说的动态编程方法是否有任何不同。最多有 2N 个匹配项,因此在某些输入上,这需要很长时间。

更新:看起来应该也可以直接解决“最后一个字符匹配”问题,而不是将其简化为普通问题。假设在 S2 中出现 2 次 Z:S2="ab...pZq...yZ"。 (无论如何都可以忽略最后一个 Z 之后的所有字符)。可以从 S2 构建一个正则表达式:".*a?.*b?.*…p?.*(Z|Z?.*q?.*…y?.*Z)"。更多的事件以相同的方式处理。需要一个看似多余的正则表达式来维持正确的匹配数量(不仅仅是存在匹配的事实)。

【讨论】:

  • 你确定这是一个正则表达式问题吗?没有办法用 DP 解决?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多