【问题标题】:Eliminate consecutive duplicates消除连续重复
【发布时间】:2016-05-22 15:23:26
【问题描述】:

消除列表元素的连续重复。

我的解决方案是:

compress([X,X|Xs], Q) :-
   compress([X|Xs], Q).
compress([X,Y|Xs], Q) :-
   X \= Y,
   compress([Y|Xs], QR),
   append([X], QR, Q).
compress([X|[]], Q) :-
   compress([], QR),
   append([X], QR, Q).
compress([], []).

而且,由于我是初学者而且我没有逻辑范式方面的经验,所以我请你说出我可以改进的地方,以及为什么我的解决方案不能做到最好。

例如,X \= Y 在我看来并不漂亮。

【问题讨论】:

    标签: list prolog prolog-dif logical-purity


    【解决方案1】:

    我们从谓词的名称开始。

    为什么要使用命令来表示关系?一个好的 Prolog 程序可以在所有方向使用,而命令式总是建议一个特定的方向或使用模式。因此,请选择一个声明性名称,并以通用性和 为目标。

    接下来,最一般的查询呢:

    ?- compress(Ls, Cs).
    ERROR: Out of local stack
    

    不是很好!我们预计这至少会产生一些答案。

    如果我们使用迭代深化会怎样:

    ?- 长度(Ls,_),压缩(Ls,Cs)。 Ls = Cs, Cs = [] ; Ls = Cs,Cs = [_G841]; Ls = [_G841, _G841], Cs = [_G841] ; Ls = [_G841, _G841, _G841], Cs = [_G841] 。

    嗯!很多答案都不见了!那么元素不同的情况呢?正如您已经直观地预料到的那样,正是使用不纯谓词导致了这种效果。

    因此,使用 ,即dif/2,表示两个术语不同。它可以在各个方向使用!

    此外,DCG () 在描述列表时通常很有用。

    所以,总的来说,这个怎么样:

    压缩([])-> []。 压缩([L|Ls])-> [L],compression_(Ls,L)。 压缩_([],_)-> []。 压缩_([X|Xs], L) --> ( { X = L }, 压缩_(Xs,L) ; { 差异(X,L)}, [X], 压缩_(Xs,X) )。

    我们使用接口谓词phrase/2 来处理DCG。

    用法示例:

    ?- 短语(压缩(Ls),Cs)。 Ls = Cs, Cs = [] ; Ls = Cs,Cs = [_G815]; Ls = [_G815, _G815], Cs = [_G815] 。 ?- 长度(Ls,_),短语(压缩(Ls),Cs)。 Ls = Cs, Cs = [] ; Ls = Cs,Cs = [_G865]; Ls = [_G865, _G865], Cs = [_G865] ; Ls = Cs, Cs = [_G1111, _G1114], 差异(_G1114,_G1111)。

    从这里拿走!提高确定性,找到更好的名称等。

    【讨论】:

    • 你在我脑子里搞砸了!但这是一个非常好的信息,因为它意味着一个进步! :) 。让我们试着理解:“因此,使用prolog-dif,即dif/2,表示两个术语不同。它可以在各个方向使用!”我不明白为什么我应该 dif/2 而不是 \= ?特别是,您突出显示方向。你到底是什么意思,因为我听不懂。
    • "length(Ls, _), compress(Ls, Cs). Ls = Cs, Cs = [] ; Ls = Cs, Cs = [_G841] ; Ls = [_G841, _G841], Cs = [_G841] ; Ls = [_G841, _G841, _G841], Cs = [_G841] ."。您想在该代码中向我展示什么? :)
    • “不是很好!我们希望这至少会产生一些答案。”想法,你说得对。但是这里的预期行为是什么?毕竟,compress(Ls, Cs) Ls 不是一个列表,所以它应该类似于未定义的行为(是的,我正在用 C++ 编程;))
    • 我们正在定义 关系,我们希望能够在所有模式下使用它们: 所有参数实例化:检查它们。没有实例化参数:生成一些解决方案或答案。部分实例化的参数:填写缺失的细节。您的初始谓词在以下一个或多个方面存在不足:它循环、省略答案、错误成功等。在不同的使用模式下尝试它,不仅是在一个列表完全实例化的情况下!尝试变量、部分实例化的列表等等。
    • 好的,现在我明白你的意思了。谢谢:)
    【解决方案2】:

    the answer by @mat (+1) 的基础上,为什么不提高确定性这样的情况:

    ?- 短语(压缩([a,a,b,b,b,c,c,c,c,d]),Xs)。 Xs = [a, b, c, d] ; 错误

    使用 ; false,SWI 表示目标没有确定地成功。

    我们可以通过使用if_//3—— 的类似物if_/3 来改进compression_//2

    压缩_([],_)-> []。 压缩_([X|Xs], L) --> if_(X = L, % 这一项和上一项一样吗? compression_(Xs, L), % yes: 旧的“运行”继续 ([X],压缩_(Xs,X)))。 % no: 新的“运行”开始

    示例查询:

    ?- phrase(compression([a,a,b,b,b,c,c,c,c,d]), Xs).
    Xs = [a, b, c, d].                            % succeeds deterministically
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-01
      • 1970-01-01
      • 2019-02-17
      • 2020-03-30
      • 2013-10-28
      • 1970-01-01
      • 2012-10-09
      相关资源
      最近更新 更多