序言,复制列表

Posted

技术标签:

【中文标题】序言,复制列表【英文标题】:prolog, copying lists 【发布时间】:2010-12-27 01:46:14 【问题描述】:

我试图抓住一些基本的序言,但在这个过程中有点挣扎。具体来说 - 我试图通过一个项目列表并将其逐项复制到一个新列表中。我可以让它倒车,但我发现不倒车会更棘手。

我一直在尝试以下 -

copy(L,R) :- accCp(L,R).

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

当我对此进行跟踪时 - 我可以看到正在复制的各个项目,但它们会“丢失”,并且不会形成一个不断增长的列表(在 R 中,正如我所希望的那样)。我怎样才能做到这一点?

非常感谢

【问题讨论】:

你想要和 copy_term/2 一样的行为吗? 【参考方案1】:

当原始列表为空时,您的基本案例需要将副本列表设置为空。然后,递归情况需要从列表L中取出H,并将其添加到列表R的头部:

copy(L,R) :- accCp(L,R).
accCp([],[]).
accCp([H|T1],[H|T2]) :- accCp(T1,T2).

当您调用copy 时,它会一直运行到基本情况,将R 设置为一个空列表。然后,当它恢复工作时,它不断将已知列表[H|T1] 的头部H 附加到变量列表[H|T2] 的开头。它会一直这样做,直到达到原始案例,此时R 包含L 的完整副本。

【讨论】:

谢谢,所以如果我正确理解了跟踪 - 它会在列表中向下运行,直到 accCp([],_) 为真,在这种情况下,_ 将替换为 [],然后返回再次,它确保第二个'[]'总是等于第一个?这是逻辑吗?非常感谢! 是的,这是正确的——在递归情况下,它从 L 中获取 H 并将其添加到 R 的头部。由于在基本情况下两个列表相等(空),它们将函数完成后结果相等。 如果答案还讨论了如果输入列表包含变量会发生什么,那就太好了,例如副本不应该独立于原件(与 copy_term/2 一样)。另外,打开列表应该如何复制?测试用例可以是例如"复制([A, B, c, A | X], L)"【参考方案2】:

非常简单的方法是:

clone1(X,X).

?-clone1([1,2,3],Z).
  Z=[1,2,3]

这是处理列表的一种表达方式。您想要复制或克隆列表。我的方法是将列表中的每个元素添加到要复制到另一个列表并返回另一个列表。

clone([],[]).
clone([H|T],[H|Z]):- clone(T,Z).

输出

?- clone([1,2,3,4,5],Z).
   Z=[1,2,3,4,5]

?- clone([a,b,c,d],Z).
   Z=[a,b,c,d]

?- clone([ [a,1,2] , [b,2,3] , [c,3,4] ],Z).
   Z = [[a, 1, 2], [b, 2, 3], [c, 3, 4]]

这适用于各种列表。

【讨论】:

以上是关于序言,复制列表的主要内容,如果未能解决你的问题,请参考以下文章

setof创建了许多列表而不是一个列表序言

通过给出可能的移动,在列表中移动。序言

将序言中的列表拆分为原子和整数

仅在序言中平整列表的一个级别

common_suffix/4 序言

使用 SWI 序言