字符串的后续序列

时间:2012-05-23 21:27:05

标签: python

我实现了一个python函数,它返回2个字符串的最长公共子序列。现在,我想实现一个返回任意数量字符串的最长公共子序列的函数。

我找到了3个字符串的帮助:

dp[i, j, k] = / 1 + dp[i - 1, j - 1, k - 1] if A[i] = B[j] = C[k]
              \ max(dp[i - 1, j, k], dp[i, j - 1, k], dp[i, j, k - 1]) otherwise

但我真的不明白这个暗示。 所以,如果有人能帮助我,我会感激不尽。 最好的问候,马克

4 个答案:

答案 0 :(得分:1)

对于未绑定的字符串数n,LCS问题是NPComplete。意思是,没有已知的能够解决这个问题的多项式算法。也意味着你可以放弃DP解决方案:p

这是一个启发式方法的链接,用于近似多个字符串的LCS。

http://www.aaai.org/ocs/index.php/AAAI/AAAI10/paper/download/1559/2197

答案 1 :(得分:1)

你可以在O(N log(N))时间(其中N是序列的长度组合)通过类似于带滚动哈希的二进制搜索来执行此操作。

请注意,最长公共序列的长度是最小序列smallestLength的长度。请按以下步骤操作:

初​​始化:

  • 假设最长公共子序列(我们称之为a)的长度为a = smallestLength/2

算法:

  • iteration_number += 1
  • 扫描所有列表(如果需要,可以并行执行!)并执行rolling hash;这将为每个列表生成len(列表) - (a-1)哈希值
  • 将所有哈希值插入到设置数据结构中(每个列表一组)以实现O(1)查找时间
  • 检查是否有任何哈希碰撞(取所有集合的交集):如果有一个或多个冲突,请手动确认这些位置中存在a - 长度子序列公共子序列,因为哈希可能是错误的(尽管如果你选择一个足够精细的哈希,这在实践中永远不会发生)
  • 你找到了共享序列吗?
    • 如果您找到这样的序列,请重复上述步骤,但增加假设的长度,就像在二分搜索中一样(添加smallestlength/2**iteration_number
    • 如果您没有找到这样的序列,请重复上述步骤,但减少假定的长度,就像在二分搜索中一样(减去smallestlength/2**iteration_number

答案 2 :(得分:0)

python3中的解决方案是:

<Provider store={ store }>
  <HashRouter>
    <div>
      <Switch>
        <Route path='/login' component={ Login } />
        <Route path='/' component={ App } />
      </Switch>
    </div>
  </HashRouter>
</Provider>

const App = () => (
  <div>
    <Navbar/>
    <div className='col-md-10 col-md-offset-1'>
      <Route path='/path1' component={ Component1 } />
      <Route path='/path2' component={ Component2 } />
      <Route path='/path3' component={ Component3 } />
    </div>
  </div>
)

这将读取3+个数组的输入,每个char后跟一个空格。 在每个数组之前输入数组的大小。输入将是

<强> INPUT

8

a b a c b d a b

6

b d c a b a

6

c b a c a a

<强>输出

BAA

答案 3 :(得分:0)

仅供参考:

from difflib import SequenceMatcher


def lcs_of_2(a, b):
    """
    get longest common string
    :param a:
    :param b:
    :return:
    """
    match = SequenceMatcher(None, a, b).find_longest_match(0, len(a), 0, len(b))
    return a[match[0]: match[0] + match[2]]


def lcs_of_list(*args):
    """
    get longest common string of list
    :param args:
    :return:
    """
    if len(args) == 2:
        return lcs_of_2(args[0], args[1])
    first = args[0]
    remains = args[1:]
    return lcs_of_2(first, lcs_of_list(*remains))


if __name__ == '__main__':
    a = 'abcdef'
    b = 'abbbbabcdeffff'
    c = 'bcdefff'
    print(lcs_of_list(a, b, c))

结果:

bcdef