我有一个整数列表,多次出现的任何整数都会连续出现.我想将其转换为元组列表,包含每个对象及其计数.
我已经提出了下面的内容,但是temp的返回类型存在问题:"类型'int'与类型''列表'不匹配".但是,这三种返回类型对我来说是一致的.我做错了什么?如果我所做的不是好F#而且应该以完全不同的方式完成,请也让我知道.
let countoccurences list =
match list with
| x::xs -> let rec temp list collecting counted =
match list with
| x::xs when x=collecting -> temp xs collecting counted+1
| x::xs -> (collecting,counted)::temp xs x 1
| [] -> (collecting,counted)::[]
temp xs x 1
| [] -> []
Run Code Online (Sandbox Code Playgroud)
Bri*_*ian 26
编辑:哎呀,这不回答你的问题,因为你说"连续".但我会留在这里,因为搜索问题标题的人可能会发现它很有用.
Seq.countBy 做这个.
let list = [1;2;3;4;5;6;1;2;3;1;1;2]
let results = list |> Seq.countBy id |> Seq.toList
printfn "%A" results
// [(1, 4); (2, 3); (3, 2); (4, 1); (5, 1); (6, 1)]
Run Code Online (Sandbox Code Playgroud)
这个如何?
lst |> Seq.groupBy (fun x -> x) |> Seq.map (fun (a,b) -> (a, Seq.length(b)))
Run Code Online (Sandbox Code Playgroud)
在这一行中:
| x::xs when x=collecting -> temp xs collecting counted+1
Run Code Online (Sandbox Code Playgroud)
编译器将你的代码解释为
| x::xs when x=collecting -> (temp xs collecting counted)+1
Run Code Online (Sandbox Code Playgroud)
但你想要的是
| x::xs when x=collecting -> temp xs collecting (counted+1)
Run Code Online (Sandbox Code Playgroud)
然而,即使进行了这一更改,您的算法的一个问题是该temp函数不是尾递归的,这意味着在长列表上调用时可能会导致堆栈溢出(例如countoccurences [1..10000]在我的机器上失败)。如果这对您很重要,那么您应该将temp辅助函数重写为尾递归。最简单的方法是添加一个累积列表参数,然后反转列表。
let countoccurences list =
match list with
| x::xs ->
let rec temp list collecting counted acc =
match list with
| x::xs when x = collecting -> temp xs collecting (counted+1) acc
| x::xs -> temp xs x 1 ((collecting, counted)::acc)
| [] -> (collecting, counted)::acc
temp xs x 1 []
|> List.rev
| [] -> []
Run Code Online (Sandbox Code Playgroud)