這裏是如何通過每個長度3
的n
列出了兩個操作比較快&骯髒的片段:
let rec fol f a = function
| [] -> a
| x::xs -> fol f (f a x) xs;;
let rec folB f xs a =
match xs with
| [] -> a
| y::ys -> f y (folB f ys a);;
let compareThemFor n =
let testList = List.replicate n [1;2;3]
let count = ref 0
let myCons x xs =
incr count
x :: xs
let myApp ys =
List.foldBack myCons ys
let mergelist = fol myApp []
mergelist testList |> ignore
let countA = !count
count := 0
let mergelist2 xs = folB myApp xs []
mergelist2 testList |> ignore
let countB = !count
(countA, countB)
,這就是你將獲得:
> compareThemFor 2;;
val it : int * int = (3, 6)
> compareThemFor 3;;
val it : int * int = (9, 9)
> compareThemFor 4;;
val it : int * int = (18, 12)
> compareThemFor 5;;
val it : int * int = (30, 15)
> compareThemFor 6;;
val it : int * int = (45, 18)
,你可以看到第二個更好,我希望上面的評論可以幫助你理解爲什麼。
萬一這裏是n=3
版本mergelist
:
mergelist [[1;2;3];[3;4;5];[6;7;8]]
{ second case in `fol` with `x=[1;2;3]` and `xs=[[3;4;5];[6;7;8]]` }
= fol (@) ([] @ [1;2;3]) [[3;4;5];[6;7;8]] // one @ of 0 elements = 0 operations
{ second case in `fol` with `x=[3;4;5]` and `xs=[[6;7;8]]` }
= fol (@) ([1;2;3] @ [3;4;5]) [[6;7;8]] // one @ of 3 elements = 3 operations
{ second case in `fol` with `x=[6;7;8]` and `xs=[]` }
= fol (@) ([1;2;3;3;4;5] @ [6;7;8]) [] // one @ of 6 elements = 6 operations
{ first case }
= [1;2;3;3;4;5;6;7;8] // 0+3+(3+3)=9 Operations Total
請注意,您在前面加上[1,2,3]
多次...
這顯然是功課吧?第一個問題:時間複雜性在哪?名單的長度? ..你也想知道'mergelist' /'mergelist2'的複雜性吧? ... 你能指望什麼?如果你寫下一個小例子列表的評估,它可能會有所幫助...... – Carsten
每次調用'(@)'時,都需要'O(n)',其中'n'表示您要添加的列表的長度。 – Petr
**提示**你對'@'瞭解多少?它的複雜程度取決於你給它的第一個或第二個列表的長度? ...你期望什麼方向表現得更好? – Carsten