【问题标题】:Issue in sorting SML list排序 SML 列表中的问题
【发布时间】:2019-08-20 22:08:15
【问题描述】:

我是 SML 的新手。我得到了这个排序算法来实现在每次迭代中的位置,我必须从列表中选择最小元素,将其删除并创建排序列表。

我做了下面的编码来解决这个问题。

我编写了 2 个辅助函数来从列表中提取最小元素并从列表中删除一个元素。

fun minList(x::xs) =List.foldl (fn (x,y)=> if x<y then x else y) x (x::xs);

fun remElem(x, l) =
   case l of
   [] => []
 | (x1::x2::xs) => if x1=x then (x2::xs) else (x1::xs)
;

以上两个程序运行成功。

下面是我的排序代码。

fun simpSort(xs)=
let fun aux(xs,acc)=
       case xs of
            [] =>acc
           | [x] => [x]
            | (x::xs) => let val m = minList(xs) 
                       in
                     aux(remElem(m,xs),acc@[m])
                       end
in aux(xs,[])
end;

这个排序程序出错了。

  • simpSort([3,1]);

    未捕获的异常匹配 [非详尽匹配失败] 提出于:stdIn:433.59

请指教。

【问题讨论】:

  • remElem 只处理空列表和至少包含两个元素的列表。
  • 另外,remElem 删除列表的第一个或第二个元素,仅此而已。这可能不是你想要的。
  • 谢谢。当我执行此代码时 - fun remElem (i, xs) = case xs of []=>[] | x::xs => if i = x then remElem(i,xs) else x::remElem(i,xs) 它正在删除输入字符的所有出现,我只想删除第一个出现。
  • 我不够清楚;如果第一个元素是第一次出现,则您将删除它,否则您将删除第二个元素——无论第二个元素是什么。例如,remElem(97, [1,2,97]) 将产生 [1,97]remElem(12, [1,2,97]) 也将产生。
  • 谢谢。我修改了 remElem 程序。现在很有趣 remElem(x, l) = case l of [] => [] | [x] => [] | (x1::xs) => 如果 x1=x 则 (xs) 否则 x1::remElem(x,xs) ;它给出了适当的输出。但是排序函数 SimpSort 仍然给出错误的结果。

标签: functional-programming sml smlnj


【解决方案1】:

既然您已经解决了问题,以下是一些改进代码工作版本的提示:

  • 以支持空列表的方式查找列表的最小值:

    fun minimum [] = NONE
      | minimum (x::xs) = SOME (foldl Int.min x xs)
    
  • 在从列表中删除第一次出现的元素的函数中简化模式匹配:

    fun remove (_, []) = []
      | remove (y, x::xs) =
        if x = y
        then xs
        else x :: remove (y, xs)
    
  • 结合起来写simpSort

    fun simpSort xs =
        case minimum xs of
             NONE => []
           | SOME x => x :: simpSort (remove (x, xs))
    

我不应该说这种排序算法非常低效。 :-P

【讨论】:

    猜你喜欢
    • 2020-07-09
    • 2019-04-07
    • 1970-01-01
    • 2015-07-11
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2015-01-13
    相关资源
    最近更新 更多