我需要一些帮助。我在数据库和found one question already asked中搜索了这个例子,但答案并没有真正帮助我,所以我想发布自己的问题。
任务是将连续重复的列表元素打包到子列表中:
% ?- 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]].
这是我得到的:
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).
第一种情况非常有效(H \ = T的情况)。第二个没有,我真的不知道为什么。有人可以帮助我,并根据我的解决方案解释问题?
由于
答案 0 :(得分:3)
你的第四句试图将[H|HS]
附加到结果上,这是不正确的,因为[H|HS]
是原始列表的尾部。你可以让它变得更简单 -
pack([H, H|HS], [[H|TFR]|TR]):-
pack([H|HS], [TFR|TR]).
基本上,它表示当前两个条目在输入中相同时,第一个条目(即H
)需要预先设置为通过递归调用生成的输出列表的第一个条目pack
规则。
请注意,第三个子句也可以通过将“破解”的Liste
参数替换为“破解”版本“内联”到子句的标题中来简化,并执行相同的操作输出变量Ergebnis1
。最终版本应如下所示:
pack([H, T|TS], [[H]|TR]):-
H \= T,
pack([T|TS], TR).
答案 1 :(得分:2)
前两个条款是微不足道的,看起来很好。
第三条似乎是合理的。它说如果我打包[H,T|TS]
和H \= T
,那么结果将[H]
添加到[T|TS]
打包的结果之前。
第四个条款是问题:
pack([H, H|HS], Ergebnis):-
pack([H|HS], Ergebnis1),
append([H|HS], Ergebnis1, Ergebnis).
它表示打包[H,H|HS]
的结果与打包[H|HS]
相同,然后排除[H|HS]
的所有内容。这似乎不符合逻辑。打包[H|HS]
时会发生什么事情,你会得到一些类似的内容:[[H,...,H]|X]
现在你想把另一个H
放到第一个子列表的头部。所以你应该:
pack([H, H|HS], Ergebnis):-
pack([H|HS], [HH|T]),
Ergebnis = [[H|HH]|T].
您可以使这些谓词更紧凑:
pack([], []).
pack([X], [[X]]).
pack([H,T|TS], [[H]|PTS]):-
H \= T,
pack([T|TS], PTS).
pack([H, H|HS], [[H|HH]|T]):-
pack([H|HS], [HH|T]).
...测试
| ?- 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]] ? a
no
| ?-
答案 2 :(得分:1)
我会稍微改变一下问题并将问题分解为两个更简单的任务。
我们首先需要能够将列表分区为前缀,其中包含列表头部的连续元素列表及其后缀(其他所有内容) :
partition( [] , [] , [] ) .
partition( [X] , [X] , [] ) .
partition( [X,Y|Z] , [X] , [Y|Z] ) :- X \= Y .
partition( [X,Y|Z] , [X|P] , S ) :- X = Y , partition([Y|Z],P,S) .
一旦我们有了,其余的很容易:
pack([],[]) . % packing an empty list yields the empty list
pack([X|Xs],[P,Ps]) :- % packing a non-empty list consists of
partition([X|Xs],P,T) , % - partitioning it into its prefix and suffix, and
pack(T,Ps) % - packing the suffix
. %
答案 3 :(得分:1)
为避免追加,您可以使用dcg:
pack(L, LP) :- % pack/2
phrase(pack(L), LP).
pack([]) --> []. % pack//1
pack([X]) --> [[X]].
pack([H, H1 | T]) -->
{H \= H1},
[[H]],
pack([H1 | T]).
pack([H, H | T]) -->
pack([H | T], [H]).
pack([H, H | T], P) --> % pack//2
pack([H | T], [H|P]).
pack([H, H1 | T], P) -->
{H \= H1},
[[H | P]],
pack([H1 | T]).
pack([H, H], P) -->
[[H,H|P]].