【问题标题】:Matching Multiple Lists匹配多个列表
【发布时间】:2014-02-03 08:10:53
【问题描述】:

我可以编写一个当两个列表相等时满足的谓词,例如equal([2,3],[2,3]) 将是 true 和 equal([2,3],[4,5])。会是假的。

但是,如果我想要一个列表并尝试将其与列表列表中的任何列表匹配,例如匹配([2,3],[[5,6],[4,6,2],[2,3]])。因为列表列表中的最后一个列表但匹配([2,3],[[3,4],[4,2,1]]),所以会是真的。将是错误的,因为 [2,3] 与列表列表中的任何内容都不匹配。

我在想也许我们可能需要在这里嵌套递归?知道你是怎么做到的吗?我要解决的问题要大得多,但只要能够做到这一点,我就可以解决整个问题。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    Prolog 列表的递归导航通常通过几个子句实现:第一个是停止递归并返回结果的条件;第二个包含递归调用。为此,在每个子句的头中,必须执行递归的列表通常分为两部分,将第一个元素(称为头)与列表的其余部分(称为尾)隔离开来,例如在以下:

    p(Element, [Head | Tail]) :- % ...
    

    在该递归子句中,您处理 Head 并根据结果继续调用您的谓词传递 Tail 作为第二个参数,因此实际上一次导航整个列表一个元素。

    在编写这样一个谓词时,您可以在找到您正在寻找的结果时(使用!)削减替代解决方案(有时只会产生失败),例如在您的情况下,一旦您在第一个列表和第二个列表中的元素之间找到匹配项,您就不需要进一步处理,因此应该修剪演示树中任何可能打开的分支。

    【讨论】:

    • 感谢朱利奥的回答。但是,我知道递归、基本情况、递归情况、头、尾、切割、匹配头等。我的问题是我有这样的东西:match( [2,3], [[4,5],[7 ,8],[2,3]])。我想知道您如何将我的 [2,3] 与嵌套列表匹配,即我对如何将整个列表与列表列表中的单个列表进行匹配感到困惑。我将继续努力,并发布我取得的任何进展的答案。对此有何建议?非常感谢。
    【解决方案2】:

    更新:由于嵌套列表,我想象事情会更复杂,但实际上这样简单的事情:

     match( Search, [H|_] ) :-
        Search = H, !.
    match( Search, [H|T] ) :-
        Search \= H,
        match( Search, T ).
    

    Giulio,您的回答非常有帮助,非常感谢 :)。

    【讨论】:

    • 在阅读了您对我的回答的评论后,我正要向您暗示您的第一个条款,但我看到您自己解决了。好的。无论如何,作为奖励:第一个子句可以直接写为match(Search, [Search|_]) :- !.,利用 Prolog 在搜索兼容子句时执行的底层统一。
    猜你喜欢
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多