当我鼠标移动时,nums确实是int的seq.知道发生了什么事吗?此函数行旨在等效于C#的DefaultIfEmpty Linq函数.
一般的想法是采用空格分隔的字符串行,并写出哪些出现次数.
码:
open System
[<EntryPoint>]
let main argv =
let tests = Console.ReadLine() |> int
for i in [0..tests] do
let (length, count) = Console.ReadLine()
|> (fun s -> s.Split [|' '|])
|> (fun split -> Int32.Parse(split.[0]), Int32.Parse(split.[1]))
Console.ReadLine()
|> (fun s -> s.Split [|' '|])
|> Seq.map int
|> Seq.take length
|> Seq.groupBy (fun x -> x)
|> Seq.map (fun (key, group) -> key, Seq.sum group)
|> Seq.where (fun (_, countx) -> countx = count)
|> Seq.map (fun (n, _) -> n)
|> (fun nums -> if Seq.isEmpty nums then "-1" else String.Join(" ", nums))
|> Console.WriteLine
0 // return an integer exit code
Run Code Online (Sandbox Code Playgroud)
样品输入:
3
9 2
4 5 2 5 4 3 1 3 4
因此,F#中的序列使用延迟评估.这意味着,当您使用的功能,例如map,where,take等的结果不会立即进行评估.
仅在实际枚举序列时才评估结果.当你调用时Seq.isEmpty,触发一个调用MoveNext(),导致结果序列的第一个元素被评估 - 在你的情况下,这导致一个大的函数链被评估.
在这种情况下,Seq.take如果序列没有足够的元素,则实际上会触发InvalidOperationException .这可能会让您感到惊讶,您来自C#,其中Enumerable.Take将占用所请求的元素数量,但如果到达序列的末尾可能会减少.
如果您想在F#中使用此行为,则需要替换Seq.take为Seq.truncate.