我有一项任务,我需要向右旋转一次列表。我也有一个约束,我只能使用一个谓词。似乎向左移动很容易:
([H|T], R) :- append(T, [H], R).
尽管如此,向右旋转并保持约束似乎更难。这是我的尝试:
rotate([H], H).
rotate([H|T], F) :- rotate(T,F1), append(F1,T,F).
在我看来,它完美无缺,但我只得到false
作为输出。任何帮助解决这个问题都将非常感激!
答案 0 :(得分:13)
如果你已经有一个谓词,比如向左旋转一个rotl(L, Rotated)
,你可以使用那个相同的谓词向右旋转。只需将列表放入第二个参数并保留第一个变量!
这是关系的深层理念:你可以以多种方式使用它们!
总结一下:
rotleft([E|T], R) :-
append(T,[E],R).
rotright(L, R) :-
rotleft(R, L).
以下是最常规查询,其中显示了包含所有可能解决方案的所有答案:
| ?- rotright(L,R).
L = [_A],
R = [_A] ? ;
L = [_A,_B],
R = [_B,_A] ? ;
L = [_A,_B,_C],
R = [_C,_A,_B] ? ;
L = [_A,_B,_C,_D],
R = [_D,_A,_B,_C] ? ;
L = [_A,_B,_C,_D,_E],
R = [_E,_A,_B,_C,_D] ? ;
L = [_A,_B,_C,_D,_E,_F],
R = [_F,_A,_B,_C,_D,_E] ? ;
L = [_A,_B,_C,_D,_E,_F,_G],
R = [_G,_A,_B,_C,_D,_E,_F] ? ;
L = [_A,_B,_C,_D,_E,_F,_G,_H],
R = [_H,_A,_B,_C,_D,_E,_F,_G] ?
你看到了这种模式吗?对于列表的每个长度(空列表除外),有一个答案包含所有可能的解决方案。看一下如何在一个答案中变量是相同的。我将用一个答案来说明这一点:
L = [_A,_B,_C,_D,_E,_F,_G],
\ \ \ \ \ \ \____
___ \ \ \ \ \ \
\ \ \ \ \ \ \
R = [_G,_A,_B,_C,_D,_E,_F] ? ;
这是最有趣的问题:
列表如何与向左/右旋转的列表相同?
尝试制定该查询并详细查看答案。
答案 1 :(得分:1)
重要的是要注意append/3
相当灵活。
正如您所发现的那样,左旋是很容易的。你想来自
[a,b,c]
到
[b,c,a]
通过观察,这样做只需要从列表中获取第一个项目(头部)并将其附加到列表的其余部分(尾部)。在prolog中,这很简单:
rotate_left( [] , [] ) . % rotating an empty list yields the empty list
rotate_left( [L|Ls] , Rotated ) :- % a left rotation of a non-empty list consist of decomposing it into its head and tail, and
append( Ls , [L] , Rotated ) % - appending the head to the tail.
.
正确的轮换并不困难。再次,通过观察,你想从
获得[a,b,c]
到
[c,a,b]
您需要从列表中获取 last 项,并将其添加到列表的其余部分。同样,您不需要比左旋转更多的东西:
rotate_right( [] , [] ) . % rotating an empty list yields the empty list.
rotate_right( [L|Ls] , Rotated ) :- % a right rotation of a non-empty list consists of
append( LeftPrefix , [Last] , [L|Ls] ) , % - deconstructing it into the last item and everything to its left
Rotated = [Last|LeftPrefix] % - reconstructing it with the righmost item first
.
append/3
非常强大,因为它可以将列表分解为所有可能的前缀和后缀。将[a,b,c]
输入其第三个参数:
append( Prefix , Suffix , [a,b,c] ).
并且,通过回溯,您可以获得创建列表[a,b,c]
的全套可能方法:
Prefix = [] Suffix = [a,b,c]
Prefix = [a] Suffix = [b,c]
Prefix = [a,b] Suffix = [c]
Prefix = [a,b,c] Suffix = []