将列表元素的连续重复包装到子列表中

use*_*666 5 list prolog

我需要一些帮助.我搜索了数据库,我发现有一个问题已经被问到这个例子,但答案并没有真正帮助我,所以我想发布我自己的问题.

任务是将列表元素的连续副本打包到子列表中:

% ?- pack([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
% X = [[a,a,a,a],[b],[c,c],[a,a],[d],[e,e,e,e]].
Run Code Online (Sandbox Code Playgroud)

这是我得到的:

pack([], []).
pack([X], [[X]]).
pack(Liste, Ergebnis):-
   Liste = [H, T|TS],
   H \= T,
   pack([T|TS], Ergebnis1),
   append([[H]], Ergebnis1, Ergebnis).
pack([H, H|HS], Ergebnis):-
   pack([H|HS], Ergebnis1),
   append([H|HS], Ergebnis1, Ergebnis).
Run Code Online (Sandbox Code Playgroud)

第一种情况非常有效(H\= T的情况).第二个没有,我真的不知道为什么.有人可以帮助我,并根据我的解决方案解释问题?

谢谢

das*_*ght 4

您的第四个子句尝试附加[H|HS]到结果,这是不正确的,因为[H|HS]它是原始列表的尾部。你可以让它变得更简单 -

pack([H, H|HS], [[H|TFR]|TR]):-
    pack([H|HS], [TFR|TR]).
Run Code Online (Sandbox Code Playgroud)

本质上,它表示当输入中的前两个条目相同时,第一个条目(即H)需要添加到由规则的递归调用生成的输出列表的第一个条目之前pack

请注意,第三个子句也可以通过将Liste立即“破解”的参数替换为“内联”到子句标题中的“破解”版本来简化,并对输出变量执行相同的操作Ergebnis1。最终版本应如下所示:

pack([H, T|TS], [[H]|TR]):-
    H \= T,
    pack([T|TS], TR).
Run Code Online (Sandbox Code Playgroud)

这是 ideone 上的演示。