【问题标题】:tell if a given element is in a list of doubles判断给定元素是否在双精度列表中
【发布时间】:2012-04-04 14:04:41
【问题描述】:

我有一个A = [[1,2],[2,3],[3,4],[5,5]] 形式的双打列表

我要做的是创建一个函数,如果一个数字是任何双打中的第一个数字,它将返回 true。所以somefunction(7,A) 会返回 false,somefunction(5,A) 会返回 true。

我试过这个somefunction(A,B) :- A == (B,_),但这并没有任何用处。

【问题讨论】:

    标签: list prolog tuples


    【解决方案1】:

    member([N,_],As).

    但这里有两点说明:

    首先,您真的想要[[1,2],[3,4]] 这样的列表吗?如果您总是有两个元素,请考虑使用对。也就是说,使用函子(-)/2。它通常写成Key-Value。因此你会写[1-2,3-4]。常用对列表,有keysort/2,只按照Key排序。

    其次,“名称查找”的常用成语如下:

    ..., P = (Name-Value), member(P, Dict), ...
    

    这里值得注意的是,对于对列表或我们拥有的任何其他元素,我们不需要“特殊”成员谓词。我们现在可以“按名称”或“按值”搜索,或者两者都搜索,或者都不搜索...

    【讨论】:

      【解决方案2】:

      除了自己进行递归之外,您还可以使用“高阶”谓词 maplist/3 结合 nth0/3 仅选择列表的第一个元素,然后对结果发出 member/2 调用以实现你想要:

      somefunction(Element, List) :-
          maplist(nth0(0), List, Firsts),
          member(Element, Firsts).
      

      【讨论】:

      • -1:此解决方案比直接解决方案更冗长,需要迭代源列表以构造第二个列表,然后需要迭代第二个列表。将其与直接对源列表进行尾递归迭代的直接解决方案进行对比。
      • 我发现这些反对票令人困惑。 false 和 Mog、chac 等通过解释实现相同目的的不同方法来增加这样的价值,并且不要声称最好的解决方案 - 只是一个替代解决方案。当然,为效率添加评论足以让其他人支持其他解决方案。在我看来,他们的声誉通过提供替代解决方案而提高。
      • @NicholasCarey:你错过了我回答的重点。这里有更糟糕的投票答案,但是...
      • 它并不冗长。我的变量有有意义的名称,这是唯一的区别:) 我还要补充一点,通过列表两次仍然是相同的复杂性,如果你觉得用函数式编程的常用习语思考得更好,那么你绝不应该阻止自己从使用它们。
      • @Mog:尼特:这是高er 顺序,+1 以避免任何歧义
      【解决方案3】:

      你可以像这样递归地做:

      检查该值是否位于列表的头部:

      somefunction(A,[[A,_]|_]).
      

      然后递归检查该值是否在列表的其余部分:

      somefunction(A,[BH|BT]) :- somefunction(A,BT).
      

      【讨论】:

      • 为了只保留独特的元素,所以如果A = [[1,2],[1,2],[1,2],[2,2],[4,4]] 将输出B = [[2,2],[4,4]]
      • @Vaughn Cato:直接考虑member/2。那是member([A,_],Xs)。这通常更有效:首先,它更紧凑、更易读(对于必须阅读代码的程序员来说更高效),其次,它的执行效率更高,因为member/2 通常比直接定义更具确定性。
      猜你喜欢
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 2020-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多