首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Prolog中列表中的连续相似元素的子列表

Prolog中列表中的连续相似元素的子列表
EN

Stack Overflow用户
提问于 2019-12-23 05:50:18
回答 3查看 429关注 0票数 1

我对Prolog很陌生,我想做这个问题。我们有一份名单

代码语言:javascript
运行
复制
List = [a,a,a,a,b,c,c,a,a,d,e,e,e,e]

我想把它打包到类似元素的子列表中。

代码语言:javascript
运行
复制
Pack( [a,a,a,a,b,c,c,a,a,d,e,e,e,e], Sublists)

应给予

代码语言:javascript
运行
复制
Sublists = [[a,a,a,a],[b],[c,c],[a,a],[d],[e,e,e,e]]

这就是我迄今尝试过的:

代码语言:javascript
运行
复制
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)中的函数。

提前谢谢。我试着解决这些问题:

  • P-99: 90个Prolog问题
EN

回答 3

Stack Overflow用户

发布于 2019-12-23 14:08:11

您可以通过简单的列表处理和使用SWI的dif/2来解决此类问题,从而提供一个通用的解决方案:

代码语言:javascript
运行
复制
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 ?-
票数 4
EN

Stack Overflow用户

发布于 2019-12-24 10:47:47

请注意,赫克氏溶液仍然存在一些性能问题。请查看每个解决方案的; false?这表明Prolog仍然保留了一些内存(称为选择点-实际上可能有几个这样的选择点)。然而,在许多情况下,不需要这样的选择点。下面是一个解决这个问题的解决方案(在Haskell的上下文中,名称group代替pack非常常见)

代码语言:javascript
运行
复制
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).

请注意,如何将EF相等的测试分为四种情况:

  1. 第一个E \= F,这意味着两者肯定是不同的。
  2. 然后是E == F,这意味着两者肯定是完全相同的。
  3. 然后是E = F,这是等式的一般情况,并且
  4. 一般不等式情况下的dif(E, F)

对于最后两种情况,不存在->,因为两者都可能是正确的。由于维护这么多情况非常麻烦,所以有library(reif) for SICStus斯维,它们允许更简洁地编写相同的内容:

代码语言:javascript
运行
复制
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).
票数 3
EN

Stack Overflow用户

发布于 2021-09-29 07:48:53

不使用dif/2

代码语言:javascript
运行
复制
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).
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59450679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档