在序言中反转列表的第二个列表

问题描述 投票:1回答:3

我有一个包含列表的列表,并且我想在其中每隔两个列表进行反转。我尝试了一些操作,但是如果列表中元素的数量为奇数,则最后一个列表元素会丢失...因此,最佳解决方案是将奇数列表放在首位,将偶数列表放在第二位,直到每两个列表都被反转。

我不能使用任何库。我需要递归执行或拆分它们,然后再次附加它们。到目前为止,我所做的最好的事情是只反转第一个偶数列表,并将第一个奇数和偶数列表追加到新列表中。

我尝试这样做:

reverselist(List, [List]).
reverselist([X,Y|Rest], [SnakeList|Rest2]):-
  append(X, [], Odd),
  reverse(Y, EvenList),
  append(Odd, EvenList, SnakeList),
  reverselist(Rest, Rest2).

还有这个:

 reverselist(List1, List2).
 reverselist([H|Ts], [Odd|R]):-
    not(0 is H mod 2),
    append(H, [], Odd),
    reverselist(Ts, R).
 reverselist([H|Ts], [Even|R]):-
    0 is H mod 2,
    reverse(H, Even),
    reverselist(Ts, R).

示例查询:

?- reverselist([[a,b,c],[d,a,b],[c,d,o],[b,c,d],[e,e,d]], List).

我希望结果是:

List = [ [a,b,c],[b,a,d],[c,d,o],[d,c,b],[e,e,d] ].
list recursion prolog append reverse
3个回答
1
投票

我们需要使用另一个参数创建另一个谓词以跟踪奇数或偶数位置:

reverselist(InList,OutList):- reverselist(InList,OutList, 0).

reverselist([],[],_). %base case
%case of even position
reverselist([H|T],[H|T1], 0):- reverselist(T,T1,1).
%case of odd position
reverselist([H|T],[H1|T1], 1):- reverse(H1,H), reverselist(T,T1,0).

2
投票

您还可以编写相互递归:

reverselist([],[]).
reverselist([H|T],[H|T1]):-reverselist2(T,T1).

reverselist2([],[]).
reverselist2([H|T],[H1|T1]):-reverse(H,H1), reverselist(T,T1).

0
投票

您与您的第一个变种非常接近。

代替您的

reverselist(List, [List]).
reverselist([X,Y|Rest], [SnakeList|Rest2]):-
  append(X, [], Odd),
  reverse(Y, EvenList),
  append(Odd, EvenList, SnakeList),
  reverselist(Rest, Rest2).

只需将其调整为

reverselist([],     []).               % additional clause
reverselist([List], [List]).
reverselist([X,Y|Rest], [X,EvenList|Rest2]):-
  % append(X, [], Odd),
  reverse(Y, EvenList),
  % append(Odd, EvenList, SnakeList),
  reverselist(Rest, Rest2).

这三个子句都是互斥的。

© www.soinside.com 2019 - 2024. All rights reserved.