【问题标题】:Remove duplicates from a list in SML从 SML 中的列表中删除重复项
【发布时间】:2014-01-31 08:54:55
【问题描述】:

我刚开始学习 SML 中的函数式编程,我想知道如何将以下两个函数组合成一个函数。函数isolate使用辅助函数'removes'删除任何类型('a)列表的重复项。

fun isolate [] = []
  | isolate (l as x::xs) = x::isolate(remove(x,xs))

fun remove (x,[]) = []
  | remove (x,l as y::ys) = if x = y then remove(x,ys) else y::remove(x,ys)

那么,为了更好地理解 SML 中的结构,您将如何将函数 remove 包含在隔离中?这可能看起来微不足道,但我已经考虑过了,无法弄清楚。谢谢您的帮助!

【问题讨论】:

    标签: recursion functional-programming sml smlnj


    【解决方案1】:

    一种方法是在isolate 中定义remove

    fun isolate [] = []
      | isolate (l as x::xs) =
          let fun remove (x,[]) = []
                | remove (x,l as y::ys) = if x = y
                                          then remove(x,ys)
                                          else y::remove(x,ys)
          in
            x::isolate(remove(x,xs))
          end
    

    或者,使重复数据删除成为一项功能,尽管这实际上是使用库函数List.filter 来做与remove 相同的事情。

    fun isolate [] = []
      | isolate (x::xs) = x::isolate(List.filter (fn y => y <> x) xs)
    

    【讨论】:

    • 这正是我想要的!谢谢!
    • 嘿@qaphla,当我编译你的代码时,我得到一个运算符和操作数不同意错误,我找不到错误。
    • 没关系。当您在 let 的“in”部分调用 remove 方法时,我发现了它。您没有传递正确的参数。
    【解决方案2】:

    我想针对这个问题提出以下解决方案:

    fun remove_duplicates(xs: int list) = 
        let
            fun check(xs: int list, item: int) =
                if null xs
                then false
                else if hd xs = item
                then true
                else check (tl xs, item)
            fun go_through_list(xs: int list) =
                if null xs
                then []
                else if check(tl xs, hd xs)
                     then go_through_list(tl xs)
                     else hd xs :: go_through_list(tl xs)
        in
            go_through_list(xs)
        end
    

    与@qaphla 提出的解决方案相比,它的代码行数更多

    【讨论】:

      【解决方案3】:

      我的想法:定义一个嵌套函数来检查列表中是否有重复元素:

      fun set(nums:int list)=
        let fun duplicate(x:int, l:int list)=
          if null l
          then false
          else hd l=x orelse duplicate(x,tl l)
        in
            if null nums
            then []
            else
            let val s=set(tl nums)
            in if duplicate(hd nums,s)
               then s
               else hd nums::s
            end
        end
      

      但它会给出一个列表,该列表只保留每个重复元素的最后一个。

      【讨论】:

        【解决方案4】:

        我的想法是先对列表进行排序,然后递归返回一个没有重复的新列表:

        fun remove_duplicates(l: int list) =
        if null(l)
        then []
        else if null(tl l)
        then l
        else
            let
                fun compare(x: int, y: int) = x > y
                fun sort(l: int list) = ListMergeSort.sort(compare) l
                val l_sorted = sort(l)
            in
                if (hd l_sorted) = (hd (tl l_sorted))
                then remove_duplicates(tl l_sorted)
                else (hd l_sorted)::remove_duplicates(tl l_sorted)
            end
        

        【讨论】:

          猜你喜欢
          • 2014-09-30
          • 2021-04-02
          • 2016-01-28
          • 2011-01-13
          相关资源
          最近更新 更多