使用f#返回距图中给定节点k步的节点列表

时间:2019-01-06 01:56:03

标签: f#

我正在尝试执行此练习: enter image description here 我已经有第一部分了:

let rec makeRoadMap (data:(string * string list) list) = 
    match data with
    | []-> Map.empty
    | ah::at-> (makeRoadMap at).Add(fst ah, setOfDestinations (snd ah))

我正在尝试完成此功能:

let upToManySteps (map:RoadMap) (n: int) (startCity : Destination)=

返回距起始城市n步之遥的一组城市。 我的想法是递归调用该方法以迭代距离n。但是我被困住了,请帮我找到一种方法。

2 个答案:

答案 0 :(得分:1)

除了我在评论中所说的,在第二部分中,您还应该注意Set <'T>类型和Set module函数。

在练习的第二部分中,以“安杜洛”为起始城市。

如果步骤数为1,则只需在RoadMap(set [City "Bibala"; City "Cacolo"; City "Dondo"])中返回“ Andulo”键的“值”即可。

如果步数为2,则应返回“ Bibala”,“ Cacolo”和“ Dondo”键值的并集(即set [City "Andulo"; City "Dondo"; City "Galo"]set [City "Andulo"; City "Dondo"]和{ {1}},即:set [City "Andulo"; City "Bibala"; City "Cacolo"; City "Ekunha"; City "Funda"]

因此,根据上面的示例,构建递归函数所需的函数为:set [City "Andulo"; City "Bibala"; City "Cacolo"; City "Dondo"; City "Ekunha"; City "Funda"; City "Galo"](或Seq.map)和Set.map

答案 1 :(得分:1)

这里有一个示例,展示了如何使用lambda函数参数中的模式直接分解元组,如何使用区分符(City,Roads)作为函数以及如何使用流水线以便将代码作为算法读取

  • 根据数据
  • 将列表的每个(字符串*字符串列表)元组映射到一个(城市,设置)元组
  • 将结果列表转换为集合
  • 将结果集转换为RoadMap

(字符串*字符串列表)列表->路线图

let MakeRoadMap data =
    data 
    |> List.map (fun (str, lst) -> (City str, lst |> List.map City |> Set.ofList))
    |> Map.ofList
    |> Roads

我们也可以使用函数组合运算符,避免指定可以推论的函数参数。

let makeRoadMap =
    List.map (fun (str, lst) -> (City str, lst |> List.map City |> Set.ofList))
    >> Map.ofList
    >> Roads

upToManySteps函数使用相同的方式

let rec upToManySteps roadMap steps city =
    match roadMap, steps with
    | _, n when n < 0 -> invalidArg "steps" "Must be positive"
    | _, 0            -> Set.empty |> Set.add city
    | Roads map, 1    -> map |> Map.find city
    | Roads map, n    -> map 
                         |> Map.find city  
                         |> Seq.map (fun x -> upToManySteps roadMap (steps - 1) x)
                         |> Set.unionMany