【问题标题】:Longest Common Subsequence of Three Sequences三个序列的最长公共子序列
【发布时间】:2016-03-20 21:30:37
【问题描述】:

我已经实现了我的三个序列的最长公共子序列版本,但找不到错误。但是 Coursera 评分者说我在最后一个测试用例中失败了。 这意味着算法几乎是正确的,但在特定情况下输出错误的答案。但这是什么情况?

约束:列表长度不小于1且不大于100。列表中的数字是从-10^9到10^9的整数。

import sys


def lcs3(a, b, c):
    start_b = 0
    start_c = 0
    result = []
    for i in range(len(a)):
        for j in range(start_b, len(b)):
            if a[i] == b[j]:
                for k in range(start_c, len(c)):
                    if b[j] == c[k]:
                        start_b = j+1
                        start_c = k+1
                        result.append(a[i])
                        break
                if b[j] == c[k]:
                    break
    return len(result)


def lcs3_reversed(a,b, c):
    # check reversed sequence which can be with different order
    a_rev = a[::-1]
    b_rev = b[::-1]
    c_rev = c[::-1]
    result = lcs3(a, b, c)
    result_reversed = lcs3(a_rev, b_rev, c_rev)
    if result == result_reversed:
        return result
    else:
        return result_reversed


if __name__ == '__main__':
    input = sys.stdin.read()
    data = list(map(int, input.split()))
    an = data[0]
    data = data[1:]
    a = data[:an]
    data = data[an:]
    bn = data[0]
    data = data[1:]
    b = data[:bn]
    data = data[bn:]
    cn = data[0]
    data = data[1:]
    c = data[:cn]
    print(lcs3_reversed(a, b, c))

更新:添加了lcs3_reversed功能来解决你描述的情况。反正不能通过测试用例。

输出应包含公共子序列的长度。例如,对于输入:

3
1 2 3
3
2 1 3
3
1 3 5

输出是 2,因为这 3 个列表的公共部分是 (1, 3)。

失败案例的运行时间为 0.04 秒,看起来列表相当长,因为我自己的大多数测试都运行得更快。

感谢您的帮助!

Update2:我尝试了另一个版本。首先我们找到 2 个列表的最长公共子序列,然后在我们的结果和第 3 个列表上再次使用它。

def lcs2(a, b):
    start_b = 0
    result = []
    for i in range(len(a)):
        for j in range(start_b, len(b)):
            if a[i] == b[j]:
                start_b = j+1
                result.append(a[i])
                break
    return result


def lcs2_reversed(a, b):
    # check reversed sequence which can be with different order
    a_rev = a[::-1]
    b_rev = b[::-1]
    result_reversed = lcs2(a_rev, b_rev)[::-1]
    return result_reversed

def lcs3_reversed(a, b, c):
    lcs2_str = lcs2(a, b)
    lcs2_rev = lcs2_reversed(a, b)
    lcs3_str_str = lcs2(lcs2_str, c)
    lcs3_rev_rev = lcs2_reversed(lcs2_rev, c)
    lenghts = [len(lcs3_str_str), len(lcs3_rev_rev)]
    return max(lenghts)

if __name__ == '__main__':
    an = input()
    a = input().split()
    bn = input()
    b = input().split()
    cn = input()
    c = input().split()
    print(max(lcs3_reversed(a, b, c), lcs3_reversed(a, c, b), lcs3_reversed(b, a, c),
              lcs3_reversed(b, c, a), lcs3_reversed(c, a, b), lcs3_reversed(c, b, a)))

此外,我尝试了所有的订单组合,但没有帮助......我再次无法通过最后一个测试用例。

【问题讨论】:

  • 在 PY2 上使用 raw_input() 或在 PY3 上使用 input(),而不是 sys.stdin.read()。另外,不要用户输入变量名,这是一个python函数
  • 如果有多个子序列,您的代码可能会得到错误的答案。考虑lcs3([1,2,3,4,5], [3,4,5,1,2], [1,3,4,5,2])。您的代码将返回2,这是[1,2] 子序列的长度。它忽略了较长的[3,4,5] 子序列。
  • Apero,为什么我不应该使用 sys.stdin.read()?这是一种读取多行输入的非常简单的方法。

标签: python algorithm sorting python-3.x


【解决方案1】:

您的示例与以下内容不同:

a = [1,2,7,3,7]
b = [2,1,2,3,7]
c = [1,2,3,1,7]

序列应该是[1,2,3,7](如果我理解正确的话),但问题是a的最后一个元素与bc的最后一个元素匹配,这意味着@ 987654326@ 和 start_c 设置为最后一个元素,因此循环结束。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 2011-03-01
    • 2013-12-06
    • 2011-02-25
    • 2013-02-13
    • 1970-01-01
    相关资源
    最近更新 更多