list - Prolog 压缩列表

标签 list prolog

我有一个奇怪的问题,我不知道如何解决。

我写了一个谓词,通过删除重复项来压缩列表。 所以如果输入是[a,a,a,a,b,c,c,a,a],输出应该是[a,b,c,a]。我的第一个代码有效,但项目顺序错误。所以我添加了一个 append/3 目标,它完全停止工作了。

想不通为什么。我尝试跟踪和调试,但不知道哪里出了问题。

这是我的代码,它可以工作但是项目顺序错误:

p08([Z], X, [Z|X]).
p08([H1,H2|T], O, X) :-
    H1 \= H2,
    p08([H2|T], [H1|O], X).
p08([H1,H1|T], O, X) :-
    p08([H1|T], O, X).

这是较新的版本,但它根本不起作用:

p08([Z], X, [Z|X]).
p08([H1,H2|T], O, X) :-
    H1 \= H2,
    append(H1, O, N),
    p08([H2|T], N, X).
p08([H1,H1|T], O, X) :-
    p08([H1|T], O, X).

最佳答案

H1 不是列表,这就是 append(H1, O, N) 失败的原因。 如果将 H1 更改为 [H1],您实际上会得到与第一个解决方案相同的解决方案。为了真正反转累加器中的列表,您应该更改前两个参数的顺序:append(O, [H1], N)。此外,您应该将第一个规则更改为与空列表 p08([], X, X) 匹配的规则(没有它,目标 p08([], [], Out) 失败)。

现在,为了解决您的问题,这是最简单的解决方案(它已经是尾递归的,正如@false 在对该答案的评论中所述,因此不需要累加器)

p([], []).                    % Rule for empty list
p([Head, Head|Rest], Out):-   % Ignore the Head if it unifies with the 2nd element
    !,                        
    p([Head|Rest], Out).
p([Head|Tail], [Head|Out]):-  % otherwise, Head must be part of the second list
    p(Tail, Out).

如果你想要一个类似于你的(使用累加器):

p08(List, Out):-p08(List, [], Out).

p08([], Acc, Acc).
p08([Head, Head|Rest], Acc, Out):-
    !,
    p08([Head|Rest], Acc, Out).
p08([Head|Tail], Acc, Out):-
    append(Acc, [Head], Acc2),
    p08(Tail, Acc2, Out).

关于list - Prolog 压缩列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24345349/

相关文章:

python - 将列表随机分成两个或三个项目的 block

序言存在时不给我解决方案

prolog - 非平凡的 Prolog 查找和替换

序言 : Divide word on syllables using predicate "Name"

prolog - 如何在prolog编程中定义谓词?

prolog - 简单的 Prolog 程序 - 不确定结果

python - 根据组编号将数组数组排序

python - 交换不相等列表切片的优雅方法?

c++ - 取消引用的列表迭代器段错误

python - 通过Python查找列表中特定位置的绝对最大值或最小值