假设我有一个decimal*decimal
let tup = [(1M, 2M); (2M, 3M); (3M, 3M); (4M, 5M); (5M, 6M); (7M, 6M); (8M, 9M); (10M, 9M)]
如果可以连接所有值,我需要一个可以将所有值组合在一起的函数,例如
map[(100, [1M; 2M; 3M]); (101, [4M; 5M; 6M; 7M]); (102, [8M; 9M; 10M])]
我不能只做一个List.groupBy
,因为这会错过任何其他可能连接起来的"线下"通过另一个十进制值。地图中的int
值是任意的。我希望能够种子"然后,起始值逐渐增加一些值。
该功能看起来能做什么?
答案 0 :(得分:3)
我是对的,通过'连接'你的意思是数字代表节点而元组代表无向图中的边?据我所知,标准库中没有功能可以做到这一点。您可以搜索执行基本图形操作的某个库。您要执行的操作是划分为connected components。
您也可以尝试从头开始实现该功能。 这是一些nice attempt。
答案 1 :(得分:2)
您尝试完成的似乎已经得到充分解决;关于如何完成它,这是一种方法:
let groupConnected initId idTups =
let mergeGroups projectIds input =
(List.empty<SortedSet<_>>, input)
||> List.fold (fun groups x ->
let ids = projectIds x
match groups |> List.tryFind (fun g -> g.Overlaps ids) with
| Some g -> g.UnionWith ids
groups
| _ -> ids::groups)
idTups
|> mergeGroups (fun (a, b) -> SortedSet([| a; b |]))
|> mergeGroups id
|> List.sortBy (fun g -> g.Min)
|> Seq.mapi (fun i g -> initId + i, List.ofSeq g)
|> Map.ofSeq
使用此问题和后续问题的输入进行测试:
> groupConnected 100 [(1M, 2M); (2M, 3M); (3M, 3M); (4M, 5M); (5M, 6M); (7M, 6M); (8M, 9M); (10M, 9M)];; val it : Map<int,decimal list> = map [(100, [1M; 2M; 3M]); (101, [4M; 5M; 6M; 7M]); (102, [8M; 9M; 10M])] > groupConnected 100 [(1M, 1M); (2M, 18M); (3M, 3M); (4M, 5M); (5M, 24M); (24M, 6M); (7M, 6M); (8M, 9M); (10M, 9M)];; val it : Map<int,decimal list> = map [(100, [1M]); (101, [2M; 18M]); (102, [3M]); (103, [4M; 5M; 6M; 7M; 24M]); (104, [8M; 9M; 10M])]
的 Online Demo 强>
答案 2 :(得分:1)
这是一个不太漂亮的解决方案:
let tup = [(1M, 2M); (2M, 3M); (3M, 3M); (4M, 5M); (5M, 6M); (7M, 6M); (8M, 9M); (10M, 9M)]
let findGroupings lst =
let rec findGroup input previous acc =
match input with
| [] -> acc
| (a,b)::t ->
match previous with
| [] -> if a >= b then
findGroup t [] acc
else
findGroup t [b;a] acc
| h::_ -> if a > h && a < b then
findGroup t (b::(a::previous)) acc
elif a > h && a >=b then
let full = List.rev (a::previous)
findGroup t [] (full::acc)
elif a >= b then
findGroup t [] ((List.rev previous)::acc)
elif a < h then
findGroup t [b;a] (previous::acc)
else // a = h and a < b
findGroup t (b::previous) acc
findGroup lst [] []
|> List.rev
使用
let result = findGroupings tup
给出
val result : decimal list list = [[1M; 2M; 3M]; [4M; 5M; 6M; 7M]; [8M; 9M; 10M]]