如果我有一个整数列表,如何写一个函数来确定列表中各数之间最小的正差?一个例子可以是这样的。
[1; 3; 5; 6] // difference 1 (between 6 and 5)
按照评论中的讨论,我不会尝试写一个完整的解决方案,但给你一个提示,关于你需要的函数,你需要让这个工作。
如果你正在寻找后续数字之间的最小差值,那么你可以使用 List.pairwise
函数,它为你提供了一个带有后续数字的元组列表。然后你可以将其传递给 List.map
将图元组列表转化为差异列表(通过从另一个图元组中减去一个图元组),并将其转化为 List.min
来寻找最小的一个。
> [1;3;5;6] |> List.pairwise;;
val it : (int * int) list = [(1, 3); (3, 5); (5, 6)]
如果你要找的是两个数字之间的最小差值,那么我会先用 List.sort
然后做与上面相同的事情--对列表进行排序将保证你需要减去最小差值的数字将彼此相邻。
现在,我将给你一个完整的解决方案,但它是通用的,所以它将适用于任何满足以下条件的类型。比较和成员约束它也可以在任何实现了 IEnumerable<'T>
. 这将使你的精力从弄清使用哪些功能转移到它们实际在做什么以及它们是如何一起工作的。
let inline smallestDiff source =
source
|> Seq.sort
|> Seq.pairwise
|> Seq.groupBy (fun (x, y) -> y - x)
|> Seq.minBy fst
// val inline smallestDiff :
// source:seq< ^a> -> ^b * seq< ^a * ^a>
// when ^a : comparison and ^a : (static member ( - ) : ^a * ^a -> ^b) and
// ^b : comparison
[1; 3; 5; 6] |> smallestDiff
// val it : int * seq<int * int> = (1, seq [(5, 6)])