使用流的SML Lazy排序的int列表

这个问题   1流和懒惰的评价(40分)      我们知道比较排序需要至少O(n log n)比较,其中正在排序n个元素。假设我们只需要排序列表中的第一个f(n)元素,对于某些函数f。如果我们知道f(n)渐近地小于log n那么对整个列表进行排序将是浪费的。我们可以实现一个惰性排序,它返回一个表示排序列表的流。每次访问流以获取排序列表的头部时,在列表中找到最小元素。这需要线性时间。从列表中删除f(n)元素将取O(nf(n))。对于这个问题,我们使用以下数据类型定义。还定义了一些辅助函数。
(* Suspended computation *)
datatype 'a stream' = Susp of unit -> 'a stream

(* Lazy stream construction *)
and 'a stream = Empty | Cons of 'a * 'a stream'
     请注意,这些流不一定是无限的,但它们可以是。      Q1.1(20分)实现函数lazysort:int list - > int stream'。      它采用整数列表并返回表示排序列表的int流'。这应该在恒定的时间内完成。每次强制流'时,它给出Empty或Cons(v,s')。在cons的情况下,v是排序列表中的最小元素,s'是表示剩余排序列表的流'。力应该是线性时间。例如:
- val s = lazysort( [9, 8, 7, 6, 5, 4] );
val s = Susp fn : int stream'
- val Cons(n1, s1) = force(s);
val n1 = 4 : int
val s1 = Susp fn : int stream'
- val Cons(n2, s2) = force(s1);
val n2 = 5 : int
val s2 = Susp fn : int stream'
- val Cons(n3, s3) = force(s2);
val n3 = 6 : int
val s3 = Susp fn : int stream'
相关定义 以下是代码:
(* Suspended computation *)
datatype 'a stream' = Susp of unit -> 'a stream

(* Lazy stream construction *)
and 'a stream = Empty | Cons of 'a * 'a stream'

(* Lazy stream construction and exposure *)
fun delay (d) = Susp (d)
fun force (Susp (d)) = d ()

(* Eager stream construction *)
val empty = Susp (fn () => Empty)
fun cons (x, s) = Susp (fn () => Cons (x, s))

(*
Inspect a stream up to n elements 
take : int -> 'a stream' -> 'a list
take': int -> 'a stream -> 'a list
*)
fun take 0 s = []
| take n (s) = take' n (force s)
and take' 0 s = []
| take' n (Cons (x, xs)) = x::(take (n-1) xs)
我尝试解决方案 我尝试执行以下操作来获取int列表并将其转换为int stream':
(* lazysort: int list -> int stream' *)
fun lazysort ([]:int list) = empty
| lazysort (h::t) = cons (h, lazysort(t));
但是当调用force时它不会返回最小元素。我必须搜索最小值,但我不知道如何...我想做插入排序如下:
fun insertsort [] = []
| insertsort (x::xs) =
let fun insert (x:real, []) = [x]
| insert (x:real, y::ys) =
if x<=y then x::y::ys
else y::insert(x, ys)
in insert(x, insertsort xs)
end;
但我必须搜索最小值,不要对列表进行排序,然后将其作为流... 任何帮助,将不胜感激。     
已邀请:
  每次访问流以获取排序列表的头部时,在列表中找到最小元素。 你在使用放置功能的正确路径上(有点......我不知道为什么你有
real
类型而不是int当只有
int streams
。如果你现在还没有意识到,你的模式将不匹配)。
   fun insertsort ([]:int list) = empty  
   | insertsort (h::t) =  
    let   
        fun insert (x:real, []) = [x] (* 1 *)
        | insert (x:real, y::ys) =    (* 2 *)
            if x<=y then x::y::ys     (* 3 *)
            else y::insert(x, ys)     (* 4 *)
    in insert(x, insertsort xs)       (* 5 *)
这是你每次获得最小项目的内在魔力。 一些提示/提示,使上述工作 你应该只有一个参数 我认为小于或等于(只是应该少于工作......并没有真正想到这一点)并不重要。此外,你必须首先到达列表的底部,告诉哪个是最小的,所以这是尾部优先。所以(* 1 *)是第一个然后每个内部调用(* 2 *)直到最外面的一个。 那个应该是
cons(x, insertsort xs)
in(* 5 *),因为你要用函数返回一个
int stream'
。     
我在你的班上,我认为你这是完全错误的方式。我已经解决了这个问题,但我认为与你完全分享代码对我来说有点不道德。那就是说,这是一个指针: 你不需要将int列表转换为int流'。首先,这违反了必须在恒定时间内完成对lazysort的初始调用的规则。请注意,将其转换为int流'是在线性时间内完成的。您需要做的是在您返回的挂起流的闭包内提供嵌入式排序函数(使用let块。)流的第一个元素是sort函数的结果(使用挂起的闭包完成)。 )流的第二个元素(它只是一个int流')应该是对lazysort函数的调用,因为它返回一个int流'。请注意这是如何让您避免必须转换它。 sort函数本身非常简单,因为您只需要找到最小的元素并返回列表的其余部分,而不会找到最小的元素。     

要回复问题请先登录注册