我们正在用F#实现这个算法。
以下是关于算法使用的符号的更多信息from Topor (1982):
正式地,
't list
是null
(表示为nil
)或hd
('t
}和tl
}(这是一个't list
)...如果x
是一个列表,我们通过编写null
来测试它是否为null x
...我们创建一个新列表,通过编写a
在现有列表x
的前面添加元素a:x
...我们用a
表示包含元素list(a)
的单元列表......list(x) = x:nil
。
我们想知道的是F#如何表达nil
,null
和list(nil)
值。例如,我们应该使用Option类型,空列表还是其他什么?
let rec kpermute k (xs: 't list) =
let rec mapPerm k xs ys =
match ys with
| [] -> []
| head::tail ->
let kpermuteNext = kpermute (k-1) (removeFirst head xs)
let mapPermNext = mapPerm k xs tail
mapcons head kpermuteNext mapPermNext
match k with
| 0 -> [[]]
| _ when xs.Length < k -> []
| _ -> mapPerm k xs xs
使用列表时,对于list(nil)
我们使用[[]]
而对于nil
,我们使用[]
。虽然这很好,但可能有一种更具表现力的方式。我们还有时候在类型推断需要更多信息时使用List.empty<'t list>
和List.empty<'t>
。
答案 0 :(得分:5)
本文为您提供了所有答案:nil
为[]
; null x
是对x
是否为空列表的测试; list(nil)
为[[]]
。
算法B到F#的简单翻译如下:
let rec minus a = function
| [] -> failwith "empty list"
| xh :: xt -> if xh = a then xt else xh :: minus a xt
let rec permute2 k x =
if k = 0 then [[]]
elif List.length x < k then []
else mapperm k x x
and mapperm k x = function
| [] -> []
| yh :: yt -> mapcons yh (permute2 (minus yh x)) (mapperm x yt)
and mapcons a ps qs =
match ps with
| [] -> qs
| ph :: pt -> a :: ph :: mapcons a pt qs