【发布时间】:2018-10-19 19:35:29
【问题描述】:
假设我们有以下序列:
[1, 2, 1, 1]
我们想根据以下规则计算这个给定序列的所有子序列:
if s_i <= s_i+1 then s_i+1 is part of a subsequence with s_i
通过从序列的第一个元素(此处为 1)开始计算子序列,并将其与它的右邻居(此处为 2)进行比较。如果它们适用于条件,则形成子序列。之后,2 必须与它的右邻居1 进行比较,如果它们适用,它就会加入子序列。在这里他们没有,所以它不加入。
此过程以2 和前一个邻居的邻居1 继续,直到序列结束。之后,以类似方式继续处理2 的邻居。
下图展示了序列中第一个元素1的子序列构建过程:
因此,问题本质上是递归的。代码如下:
def calc(seq):
for i in range(0, len(seq)):
calc_subseq(i, seq)
def calc_subseq(i, seq):
a = seq[i]
for j in range(i+1, len(seq):
b[j] = seq[j]
if b <= a:
calc_subseq(j, seq);
else:
#build subsequence
#build subsequnce
现在的问题是:
计算后如何检索子序列?我使用了一个堆栈,并在每次调用时都传递了它。此外,我还传递了一个计数器,该计数器随着每次匹配而增加,并随着每个函数调用传递,然后也返回。如果不匹配,我会从堆栈中弹出与计数器计数一样多的项目。当在calc_subseq(seq) 中到达 for 循环的结尾时,我也会这样做。但我正在寻找更好的解决方案。
有人知道解决类似问题的算法吗?如果有更有效的方法会很有趣。我想到了某种动态编程。
编辑:
根据要求,这里是输入序列[1,2,1,1]的所有结果:
1 (0), 2 (1)
2 (1)
2 (1)
2 (1) -> end
1 (0), 1 (2), 1 (3)
1 (3) -> end
1 (2) -> end
1 (0), 1(3)
1 (3) -> end
1 (0) -> end
2 (1)
2 (1)
2 (1) -> end
1 (2), 1 (3)
1 (3) -> end
1 (2) -> end
1 (3) -> end
注意:索引以(x) 提供。 -> end 表示已到达第二个 for 循环的末尾。因此,它显示了由于没有邻居剩下而无法比较的最后一个元素。
【问题讨论】:
-
您所描述的内容听起来像是在寻找“单调序列”。 This question 对此有一些想法
-
那么
[1, 2, 1, 1]的结果应该是怎样的呢?我必须说我不确定我是否理解你所描述的算法。另外,您能否添加更多示例以及您期望的结果? (像 2 或 3 就足够了)。 -
当然,我已经为序列中的第一个元素 (1) 添加了结果。
-
我不明白你是如何得到
[1, 1, 1]子序列的——正如我理解的解释,我以为你只会得到[1], [1, 2], [2], [1], [1, 1].. -
我猜我的解释很复杂。我觉得很难用语言来解释。我稍后会改变它,可能会添加一张图片,这样更容易。这里的问题是,每个元素都与它的所有邻居进行比较。如果发生匹配,则过程继续匹配元素。这就是我需要递归的原因。