我构建了一个简单的函数,告诉我给定元素在列表中的实际位置。第一个位置是0:
let rec foo79 =
fun k l ->
match k, l with
| k, [] -> failwith "What you are lookig for is not here"
| k, (x::xs) -> if x = k then 0
else 1 + foo79 k xs
这很简单而且有效(即便如此,欢迎提出改进它的每一个建议!)。
在x
出现倍<的情况下,我使用此功能无法做到告诉我x
的位置 / strong>列表中的次数。
到目前为止,我的尝试甚至都没有接近解决方案。我实际发布它只是为了让你成为我追求的方法的一个例子。
let rec foo79b =
fun k l ->
match k, l with
| k, [] -> failwith "What you are lookig for is not here"
| k, (x::xs) -> if x = k & (x::xs) then 1 + foo79b k xs
elif x = k & [] then 0
else 1 + foo79b k xs
答案 0 :(得分:2)
您的函数需要返回一个位置列表,因此您可以使用累加器作为结果列表。同时,您可以使用另一个辅助参数来处理索引,而不必在呼叫站点求和:
let findAllPos elem lst =
let rec foo79 =
fun k l i acc ->
match k, l with
| k, [] -> acc
| k, (x::xs) -> if x = k then foo79 k xs (i+1) (i::acc)
else foo79 k xs (i+1) acc
foo79 elem lst 0 []
通过这种方式,它变得更简单,更重要的是使您的解决方案成为tail recursive。如果您不相信我尝试使用此foo79 400000 [0..400000]
调用您的第一个函数,请尝试我提议的findAllPos 400000 [0..400000]
。
答案 1 :(得分:1)
let positions (x: 'a) (xs: 'a seq) : int seq =
xs
|> Seq.mapi (fun i y -> if y = x then Some i else None)
|> Seq.choose id
// [0; 0; 2; 3; 4; 0; 6] |> positions 0;;
// val it : seq<int> = seq [0; 1; 5]
也适用于序列。
这个只适用于列表(不是序列),可能很慢:
let positions' (x: 'a) (xs: 'a list) : int list =
[0..(Seq.length xs - 1)]
|> List.filter (fun i -> xs.[i] = x)
// [0; 0; 2; 3; 4; 0; 6] |> positions' 0;;
// val it : int list = [0; 1; 5]