【问题标题】:remove elements from a list in ml从 ml 列表中删除元素
【发布时间】:2013-08-19 22:39:51
【问题描述】:

我正在尝试编写一个函数来生成一个包含给定列表但不包含元素 x 的新列表。

Moscow ML 表示本场比赛中没有使用某些情况。

fun delete (x,list) = delete(x,[])
 |delete(x,(first::rest)) = if first = x then delete(x,rest) else first::delete(x,rest)

【问题讨论】:

    标签: sml ml


    【解决方案1】:

    那是因为您的第一个 case 匹配 any 列表,所以永远不会使用第二个 case。
    请记住,案例是按照编写顺序进行审理的,而不是根据哪个是“最佳”匹配来选择的。

    你还有一个无限递归的小问题

    delete (x,list) = delete(x,[])
    

    由于list 将匹配[],它将永远递归。
    如果从空列表中删除某些内容,结果应该是空列表。

    你可以做两件事之一。

    要么先移动非空的情况:

    fun delete (x, y:ys) = if y = x then delete(x, ys) else y::delete(x, ys)
      | delete (x, list) = []
    

    或者,更常见的是,让第一种情况只匹配空列表:

    fun delete (x, []) = []
      | delete (x, y:ys) = if y = x then delete(x, ys) else y::delete(x, ys)
    

    【讨论】:

    • 对不起,这部分delete (x, list) = [] 到底是干什么用的?我无法以这种递归方式理解这部分的作用。谢谢
    • @Huzo 这是递归的基本情况,什么都不做。我保留了原始代码中的名称“列表”。你也可以写[],或者_
    【解决方案2】:

    当调用delete 时,定义函数的模式(基本上)按顺序尝试。由于第一个模式已经匹配每个列表,因此永远不会到达第二个模式。这就是编译器抱怨的原因。

    换句话说,您要么必须重新排序您的案例,或者更好地使它们不相交(例如,在第一个案例中将 list 替换为 [])。

    额外提示:第一种情况的右侧似乎也有误。这将始终进入无限递归。

    【讨论】:

      【解决方案3】:

      这是我在标准 ML 上的做法::

      fun delete (item, list) =
          case list of
          []=>[]
            | xs::ys => if item = xs then delete(item,ys)
                else xs::delete(item,ys)
      

      不使用案例:

      fun delete (item, list) = List.filter(fn x => x <> item) list
      

      不要介意多等号。

      【讨论】:

      • 如果没有...的案例列表,我该怎么写?认为我的代码看起来很安静,所以也许我不会做太多错误:)
      • 如果您不想使用用例,那么我建议您执行以下操作: fun delete (item, list) = List.filter(fn x => x item) list
      猜你喜欢
      • 2021-06-09
      • 1970-01-01
      • 2017-03-05
      • 2014-12-19
      • 2013-11-25
      相关资源
      最近更新 更多