在Prolog中查找所有列表轮换

时间:2014-05-17 13:32:11

标签: list rotation prolog

我正在尝试在Prolog中生成所有可能的列表轮换。这是一个例子:

rotate([1,2,3], X).
X = [1,2,3];
X = [2,3,1];
X = [3,1,2].

我找到了一种旋转的方法:

rotate([H|T], R) :-
    append(T, [H], R).

但如何找到所有?

答案

rotate(L, R) :-
    append(Left, Right, L),
    append(Right, Left, R),
    Right \= [].

1 个答案:

答案 0 :(得分:4)

您可以使用append/3谓词将列表拆分为前缀和后缀。例如:

?- append(Prefix, Suffix, [1,2,3]).
Prefix = [],
Suffix = [1, 2, 3] ;
Prefix = [1],
Suffix = [2, 3] ;
Prefix = [1, 2],
Suffix = [3] ;
Prefix = [1, 2, 3],
Suffix = [] ;
false.

然后,在前缀后附一个后缀会给你一个轮换:

| ?- append(_Prefix, _Suffix, [1,2,3]), append(_Suffix, _Prefix, Rotation).

Rotation = [1,2,3] ? ;
Rotation = [2,3,1] ? ;
Rotation = [3,1,2] ? ;
Rotation = [1,2,3]
yes

但是有一个冗余的解决方案。你能摆脱它吗?提示:如果前缀或后缀是空列表,则会获得原始列表。