普罗格误会.将列表拆分为两个具有偶数和奇数位置的列表.我的错误在哪里



我正在尝试将一个列表拆分为另外两个列表。列出偶数,偶数与偶数位置和列表奇数与其他。我一直在互联网上寻找解决方案,但在我看来都像中国人,我无法理解这个过程。 所以这就是我一直在尝试的:

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。

我不知道我做错了什么。 我会感谢任何帮助。谢谢!

CapelliC的答案是完美的。只是为了解释:

当你有一个这样的Prolog子句时:

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

然后你这样称呼:

?- foo([a,b,c], L).来自: foo([H| T ], [H|Z]) 时 H = a, T = [b,c],L = [a|Z]呼叫: foo([a|[b,c]], [a|Z])

然后导致递归调用:

呼叫: foo([b,c], Z).来自: foo([H| T ], [H|Z]) H = b, T = [c]L = [b|Z]呼叫: foo([b|[c]], [b|Z])

此时,您在开头所做的列表[a|Z]现在[a|[b|Z]],这是[a,b|Z]

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

foo([], []).

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

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

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

你的想法必须完善...

首先,每种语言(不仅是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([],[],[]). 
我知道

这篇文章现在已经很旧了,但我想我也会添加我的解决方案,所以如果有像我 15 分钟前这样的人,他们还有其他东西要看。这种方式以向后构建列表以创建最终列表。前 3 行是基本情况。

    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).

最新更新