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

时间:2014-05-14 17:05:07

标签: list prolog

我需要一些帮助。我在数据库和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的情况)。第二个没有,我真的不知道为什么。有人可以帮助我,并根据我的解决方案解释问题?

由于

4 个答案:

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

Here is a demo on ideone.

答案 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)

为避免追加,您可以使用

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