prolog误解。将列表拆分为两个列表,包含偶数和奇数位置。我的错误在哪里?

时间:2015-06-16 08:11:32

标签: list split prolog

我正在尝试将列表拆分为另外两个列表。列表即使是偶数的元素和其他的列表奇怪。我一直在寻找iinternet的解决方案,但在我看来都像中文,我无法理解这个过程。所以这就是我一直在尝试的:

split(List,Odd,Even):-odd(List,Oddlist,Evenlist).

odd([H|T],Oddlist,Evenlist):-even(T,[H|Oddlist],Evenlist).
odd([],_,_).

even([H|T],Oddlist,Evenlist):-odd(T,Oddlist,[H|Evenlist]).       
even([],_,_). 

但我得到的唯一回报是像Oddlist = _7132946 Evenlist = _26997888。

我不知道我做错了什么。我会帮助你。谢谢!

3 个答案:

答案 0 :(得分:3)

CapelliC的答案是完美的。只是解释一下:

如果你有这样的Prolog条款:

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

然后你可以这样打电话:

?- foo([a,b,c], L).
from: foo([H|  T  ], [H|Z]) with H = a, T = [b,c], L = [a|Z]
call: foo([a|[b,c]], [a|Z])

然后导致递归调用:

call: foo([b,c], Z).
from: foo([H|  T  ], [H|Z]) with H = b, T = [c], L = [b|Z]
call: foo([b|[c]], [b|Z])

此时,您在开头制作的列表[a|Z]现在为[a|[b|Z]],即[a,b|Z]

因此,您在作为第二个参数传递的变量中创建一个列表,并在列表的前面粘贴 H 。您给递归调用的列表的其余部分。您将继续在列表末尾添加元素,直到第一个列表为空列表。此时,您也将结束新列表:

foo([], []).

在您的示例中,有另一个谓词与第一个谓词相互递归:

foo([], [], []).
foo([H|T], [H|F], B) :-
    bar(T, F, B).

bar([], [], []).
bar([H|T], F, [H|B]) :-
    foo(T, F, B).

当然,这将"解压缩"列表分为两个列表。

答案 1 :(得分:2)

你的想法必须改进......

首先,每种语言(不仅是Prolog)都需要符号一致地命名。所以我根据需要重命名了变量。

特定于Prolog,有一种特殊的方法可以使用'cons'列表,这些列表源自规则头上应用的模式匹配。这同样适用于基本情况:我们必须提供将在调用者中绑定变量的空列表。

整个代码:

split(List,Odd,Even):-odd(List,Odd,Even).

odd([H|T],[H|Odd],Even):-even(T,Odd,Even).
odd([],[],[]).

even([H|T],Odd,[H|Even]):-odd(T,Odd,Even).       
even([],[],[]). 

答案 2 :(得分:0)

我知道这篇文章现在已经很老了,但我想我也会添加解决方案,因此,如果有15分钟前像我这样的人,他们还有其他需要注意的地方。这种方式将列表向后建立,以创建最终列表。前三行是基本情况。

    split_odd_even([], [], []).
    split_odd_even([O], [O], []).
    split_odd_even([O,E], [O], [E]).
    split_odd_even([O,E|T], [O|OL], [E|EL]) :- split_odd_even(T, OL, EL).