简体   繁体   English

如何使用地图构建列表?

[英]How to build a list using a Map?

First of all, I have those types :首先,我有这些类型:

type position = float * float

type node = position

To build my Map I've written those modules :为了构建我的地图,我编写了这些模块:

module MyMap =
  struct
    type t = Graph.node
    let compare (a1,b1) (a2,b2) =
      if a1 > a2 then 1
       else if a1 < a2 then -1
       else if b1 > b2 then 1
       else if b1 < b2 then -1
       else 0
  end

module DistMap = Map.Make(MyMap)

In my case, I'll have a previousMap that has type val previousMap : (float * float) DistMap.t = <abstr> It contains nodes as key, and values.在我的情况下,我将有一个previousMap具有类型val previousMap : (float * float) DistMap.t = <abstr>它包含节点作为键和值。 Let's say it is built like this :假设它是这样构建的:

DistMap.bindings prevMap;;
- : (node * (float * float)) list =
[((1., 1.), (2., 2.)); 
((2., 2.), (3., 3.)); 
((3., 3.), (4., 4.));
((4., 4.), (5., 5.))]

It means that (2.,2.) is the predecessor node of (1.,1.) in a graph.这意味着 (2.,2.) 是图中 (1.,1.) 的前驱节点。

What I am aiming for is to build the list that represent the path from a source node to a target node.我的目标是构建表示从source节点到target节点的路径的列表。

For example, if I had :例如,如果我有:

let build_path prevMap source target

The expected output using the previousMap would be a node (or float * float) list like this :使用previousMap的预期输出将是一个node (or float * float) list如下所示:

build_path previousMap (1.,1.) (5.,5.) -> [(1.,1.);(2.,2.);(3.,3.);(4.,4.);(5.,5.)]

So far my attempts consisted in trying to use the fold and iter function on the previousMap but they were inconclusive.到目前为止,我的尝试包括尝试在previousMap上使用folditer函数,但它们没有定论。

Update :更新 :

Here's an attempt I think could be close to what I want to achieve :这是我认为可能接近我想要实现的尝试:

let build_list map source target =
  let rec build_aux acc map source x =
    if ((DistMap.find x map)) = source then source::acc
    else build_aux (DistMap.find x map)::acc source (DistMap.find x map)
    in build_aux [] map source target

However I get this error output :但是我得到这个错误输出:

356 |     else build_aux (DistMap.find x map)::acc source (DistMap.find x map)
                         ^^^^^^^^^^^^^^^^^^^^
Error: This expression has type 'a but an expression was expected of type
         'a list
       The type variable 'a occurs inside 'a list

Update 2 :更新2:

The issue has been solved, however the function isn't behaving as expected.问题已解决,但功能未按预期运行。 Basically this is the pseudo-code I'd like to implement :基本上这是我想要实现的伪代码:

伪代码

How could I proceed to build such a list?我怎样才能继续建立这样的清单?

Thanks.谢谢。

The problem with fold and iter is that they process nodes in an order that they determine themselves. folditer的问题在于它们按照它们自己确定的顺序处理节点。 In essence the order is based on the shape of the map, which is determined by the keys.本质上,顺序是基于地图的形状,由键决定。 You want to process the nodes of the map in an order determined by the values in the map.您希望按照地图中的值确定的顺序处理地图的节点。

I'm pretty sure the only way to proceed is to write your own special-purpose recursive function.我很确定继续进行的唯一方法是编写自己的特殊用途递归函数。

Update更新

In the latest code you have this expression:在最新的代码中,你有这个表达式:

build_aux (DistMap.find x map)::acc source (DistMap.find x map)

The operator precedence in OCaml that binds function arguments to functions is very tight, so this gets parsed like this: OCaml 中将函数参数绑定到函数的运算符优先级非常严格,因此解析如下:

(build_aux (DistMap.find x map)) :: (acc source (DistMap.find x map))

You need parentheses around this subexpression:您需要在此子表达式周围加上括号:

((DistMap.find x map)::acc)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM