Prolog - 列表中最常见的长度为N的序列

时间:2017-11-01 02:29:30

标签: list prolog logic sequence

我试图找到列表中出现的最常见的长度N序列。所以我应该写一个谓词common(L,N,X),它以列表的形式给我这个序列。例如:common([1,2,3,2,3,1,4],2,X)应该给我回复X=[2,3]; common([1,2,3,4,2,2,2,3,4],3,X)应该返回X=[2,3,4]common([1,2,3],1,X)应该给X=[1] X=[2] X=[3]

当我们只寻找最常见的元素时,我已经阅读了几篇帖子(所以N = 1的情况),但我不知道如何为一般的N做这个。我不被允许使用if -then-else或clpfd。

我在考虑对元素进行分组然后对它们进行排序,因此common([1,2,3,2,3,1,4],2,X)创建一个像[[1,2],[2,3],[3,2],[2,3],[3,1],[1,4]]这样的列表,然后将元素从最常见到最少排序。

1 个答案:

答案 0 :(得分:2)

我喜欢你的计划。这是我如何得到重叠的子序列。

首先,让我们获取长度为N的列表的前缀:

subsequences(L, N, Sub) :- append(Sub, _, L), length(Sub, N).

这应该被读取" Sub是列表L的长度N的子序列,如果Sub,附加到其他地方得到L,并且Sub的长度是N."这肯定会给你一个长度为N的L的前缀。现在让我们看一下递归的情况:

subsequences([_|L], N, Sub) :- subsequences(L, N, Sub).

"否则,在L的尾部找到一个子序列。"这将产生多种解决方案:

?- subsequences([1,2,3,2,3,1,4], 2, X).
X = [1, 2] ;
X = [2, 3] ;
X = [3, 2] ;
X = [2, 3] ;
X = [3, 1] ;
X = [1, 4] ;

findall/3是您的朋友,您可以使用它来构建您想要的列表:

?- findall(X, subsequences([1,2,3,2,3,1,4], 2, X), Subsequences).
Subsequences = [[1, 2], [2, 3], [3, 2], [2, 3], [3, 1], [1, 4]].

希望这有帮助!