答案 0 :(得分:7)
答案 1 :(得分:2)
答案 2 :(得分:1)
答案 3 :(得分:0)
是否存在问题,返回的结果是否已排序? 该算法将在输入序列上线性工作。只需要对索引进行排序。如果序列很大,但索引不是那么多 - 它会很快。 复杂性是:N - > Max(指数),M - >指数计数:最坏情况下为O(N + MlogM)。
let seqTakeIndices indexes =
let rec gather prev idxs xs =
match idxs with
| [] -> Seq.empty
| n::ns -> seq { let left = xs |> Seq.skip (n - prev)
yield left |> Seq.head
yield! gather n ns left }
indexes |> List.sort |> gather 0
这是一个List.fold变体,但读取起来比较复杂。我更喜欢第一个:
let seqTakeIndices indices xs =
let gather (prev, xs, res) n =
let left = xs |> Seq.skip (n - prev)
n, left, (Seq.head left)::res
let _, _, res = indices |> List.sort |> List.fold gather (0, xs, [])
res
附加:仍然比你的变种慢,但比我的旧变种要快很多。因为没有使用Seq.skip来创建新的枚举器并且正在减慢很多事情。
let seqTakeIndices indices (xs : seq<_>) =
let enum = xs.GetEnumerator()
enum.MoveNext() |> ignore
let rec gather prev idxs =
match idxs with
| [] -> Seq.empty
| n::ns -> seq { if [1..n-prev] |> List.forall (fun _ -> enum.MoveNext()) then
yield enum.Current
yield! gather n ns }
indices |> List.sort |> gather 0