Prolog 中列表的自定义反转
我正在尝试编写一个谓词,在 Prolog 中给出以下列表:
[[1,a,b],[2,c,d],[[3,e,f],[4,g,h],[5,i,j]],[6,k,l]]
将生成以下列表:
[[6,k,l],[[5,i,j],[4,g,h],[3,e,f]],[2,c,d],[1,a,b]]
正如您所看到的,我想保留最低级别的元素顺序,以生成顺序为 1, a, b 而不是 b、a、1。
我还想保留列表的深度,即最初嵌套的列表按原样返回,但以相反的顺序返回。
我已经设法使用以下代码实现了所需的顺序,但深度丢失了,即列表不再正确嵌套:
accRev([F,S,T],A,R) :- F \= [_|_], S \= [_|_], T \= [_|_],
accRev([],[[F,S,T]|A],R).
accRev([H|T],A,R) :- accRev(H,[],R1), accRev(T,[],R2), append(R2,R1,R).
accRev([],A,A).
rev(A,B) :- accRev(A,[],B).
我将不胜感激帮助纠正代码以保留列表的正确嵌套。谢谢!
I am trying to write a predicate that given the following list in Prolog:
[[1,a,b],[2,c,d],[[3,e,f],[4,g,h],[5,i,j]],[6,k,l]]
will produce the following list:
[[6,k,l],[[5,i,j],[4,g,h],[3,e,f]],[2,c,d],[1,a,b]]
As you can see I would like to preserve the order of the elements at the lowest level, to produce elements in the order 1, a, b and NOT b, a, 1.
I would also like to preserve the depth of the lists, that is, lists that are originally nested are returned as such, but in reverse order.
I have managed to achieve the desired order with the following code, but the depth is lost, i.e. lists are no longer nested correctly:
accRev([F,S,T],A,R) :- F \= [_|_], S \= [_|_], T \= [_|_],
accRev([],[[F,S,T]|A],R).
accRev([H|T],A,R) :- accRev(H,[],R1), accRev(T,[],R2), append(R2,R1,R).
accRev([],A,A).
rev(A,B) :- accRev(A,[],B).
I would appreciate help in correcting the code to preserve the correct nesting of lists. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
两个建议。首先,这是一个 (
rev_lists/2
),它使用了一堆 SWI-PROLOG 内置函数:这个通过测试列表
L
的所有元素本身是否是列表来工作(M
);如果是这样,它将递归地将自身(通过maplist
)应用于所有单独的子列表,否则它将返回相同的列表。这样就达到了需要的效果了。其次,这里又是
rev_lists/2
,但编写方式使其不依赖于除member/2
(这是常见的)之外的内置函数:它基本上是相同的策略,但使用累加器在每个级别构建反向列表,前提是它们仅由列表组成;否则,返回相同的列表。
Two suggestions. First, here's one (
rev_lists/2
) which uses a bunch of SWI-PROLOG built-ins:This one works by testing if all elements of a list
L
are themselves lists (M
); if so, it will recursively apply itself (viamaplist
) over all individual sub-lists, else it will return the same list. This has the required effect.Secondly, here's
rev_lists/2
again, but written such that it doesn't rely on built-ins exceptmember/2
(which is common):It's basically the same strategy, but uses an accumulator to build up reverse lists at each level, iff they are comprised exclusively of lists; otherwise, the same list is returned.