我对Prolog很陌生,我想做这个问题。我们有一份名单
List = [a,a,a,a,b,c,c,a,a,d,e,e,e,e]
我想把它打包到类似元素的子列表中。
Pack( [a,a,a,a,b,c,c,a,a,d,e,e,e,e], Sublists)
应给予
Sublists = [[a,a,a,a],[b],[c,c],[a,a],[d],[e,e,e,e]]
这就是我迄今尝试过的:
pack([],[],[]).
pack([H],[H],[H]).
pack([H,H1|T],Z,X):- H==H1 , append([H],Z,Z1) , pack([H1|T],Z1,X).
pack([H,H1|T],Z,X):- H=\=H1 , append([H],Z,Z1) ,
append(Z1,X,Xs) , pack([H1|T],Z1,Xs).
以下是错误:
算术:‘A/0’不是在第13行( a,a,a.,a,_1608)第13行2 pack(a,a.,a,_1688)第13行3 pack(a,b.,a,_1688)中的函数。
提前谢谢。我试着解决这些问题:
发布于 2019-12-23 14:08:11
您可以通过简单的列表处理和使用SWI的dif/2
来解决此类问题,从而提供一个通用的解决方案:
pack([], []). % packing empty is empty
pack([X], [[X]]). % packing a single element
pack([X,X|T], [[X|PH]|PT]):- % rule for packing when next two terms are the same
pack([X|T], [PH|PT]).
pack([X,Y|T], [[X]|PT]):- % rule for different term
dif(X, Y),
pack([Y|T], PT).
2 ?- pack([a,a,a,a,b,c,c,a,a,d,e,e], L).
L = [[a, a, a, a], [b], [c, c], [a, a], [d], [e, e]] ;
false.
3 ?- pack(L, [[a,a,a], [b,b], [c]]).
L = [a, a, a, b, b, c] ;
false.
4 ?-
发布于 2019-12-24 10:47:47
请注意,赫克氏溶液仍然存在一些性能问题。请查看每个解决方案的; false
?这表明Prolog仍然保留了一些内存(称为选择点-实际上可能有几个这样的选择点)。然而,在许多情况下,不需要这样的选择点。下面是一个解决这个问题的解决方案(在Haskell的上下文中,名称group
代替pack
非常常见)
group([], []).
group([E|Es], [[E|Gs]|Gss]) :-
igroup(Es, E, Gs, Gss).
igroup([], _, [], []).
igroup([E|Es], F, Gs1, Gss1) :-
( E\=F
-> Gs1=[], Gss1=[[E|Gs2]|Gss2]
; E==F
-> Gs1=[E|Gs2], Gss1=Gss2
; E=F,
Gs1=[E|Gs2], Gss1=Gss2
; dif(E, F),
Gs1=[], Gss1=[[E|Gs2]|Gss2]
),
igroup(Es, E, Gs2, Gss2).
请注意,如何将E
和F
相等的测试分为四种情况:
E \= F
,这意味着两者肯定是不同的。E == F
,这意味着两者肯定是完全相同的。E = F
,这是等式的一般情况,并且dif(E, F)
对于最后两种情况,不存在->
,因为两者都可能是正确的。由于维护这么多情况非常麻烦,所以有library(reif)
for SICStus和斯维,它们允许更简洁地编写相同的内容:
igroup([], _, [], []).
igroup([E|Es], F, Gs1, Gss1) :-
if_(E = F
, ( Gs1 = [E|Gs2], Gss1 = Gss2 )
, ( Gs1 = [], Gss1 = [[E|Gs2]| Gss2] )),
igroup(Es, E, Gs2, Gss2).
发布于 2021-09-29 07:48:53
不使用dif/2
my_pack([],[[]]).
my_pack([X], [[X]]).
my_pack([X,X|L], [F|R]) :- my_pack([X|L], [F1|R]), append([X], F1, F).
my_pack([X|L], [F|R]) :- my_pack(L, R), append([X], [], F).
https://stackoverflow.com/questions/59450679
复制相似问题