вопрос
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 ', представляющий отсортированный список. Это должно быть сделано в постоянное время. Каждый раз, когда поток «принудительно», он выдает либо «Пустой», либо «Минус» (v, s ') В случае с минусами 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;
Но мне нужно искать минимум и не сортировать список, а затем помещать его в виде потока ...
Буду признателен за любую помощь.