首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ocaml和and类型(图论)

Ocaml和and类型(图论)
EN

Stack Overflow用户
提问于 2018-06-13 11:01:04
回答 1查看 240关注 0票数 0

我只是Ocaml的乞丐,我想学习图论,但是用Ocaml实现。我很难做一些事情:我只是想用深度优先搜索来列出一个图的连通成分。所以,我做了

代码语言:javascript
复制
#open "stack" ;;

let non_empty pile = 
    try push (pop pile) pile ; true with Empty -> false ;;


let connected_comp g = 
    let already_seen = make_vect (vect_length g) false in
    let comp = [] in

    let dfs s lst = 
        let totreat = new () in
        already_seen.(s) <- true; push s totreat;

        let rec add_neighbour l = match l with
            | [] -> ()
            | q::r when already_seen.(q) = false -> push q totreat; already_seen.(q) <- true; add_neighbour r
            | q::r -> add_neighbour r
        in

        while non_empty totreat do
            let s = pop totreat in
            already_seen.(s) <- true;
            (* we want to add s to the list lst *) s::lst;
            add_neighbour g.(s);
        done
    in  


    let rec head_list l = match l with
        | [] -> failwith "Empty list"
        | p::q -> p
    in  
    let rec aux comp t = match t with
        | t when t = vect_length g -> comp
        | t when already_seen.(t) = true -> aux comp (t+1)
        | t -> aux ((dfs t [])::comp) (t+1) (* we want that dfs t [] return the list lst modified *)
    in aux comp 0;;

我得到了:

代码语言:javascript
复制
>       | t -> (dfs t [])::comp ; aux  comp (t+1) (* we want that dfs t [] return the list lst modified *)
>              ^^^^^^^^^^^^^^^^
Warning : this expression is of type unit list,
but is used with the type unit.
connected_comp : int list vect -> unit list = <fun>
- : unit list = []
- : unit = ()

当然,我一点也不惊讶。但是我想要做的是,函数dfs返回在参数上发送的列表( lst列表),但是修改了,这里不是这样的,因为函数的类型是单位,因为它没有返回任何内容。但是在Ocaml中,由于语言是用来返回我认为的最后一个表达式,所以我不知道该怎么做。我也可以对dfs函数使用递归算法,因为通过过滤,它将允许我返回列表,但我只想了解Ocaml,并对算法进行了修改(即使不是最优的)。

有人能帮我吗?

编辑:,正如我们问我的,我将尽量减少我的代码,并切入要点。所以,我有一个函数dfs,它对应于深度优先搜索(对于图)

代码语言:javascript
复制
let dfs s lst = 
    let totreat = new () in
    already_seen.(s) <- true; push s totreat;

    let rec add_neighbour l = match l with
        | [] -> ()
        | q::r when already_seen.(q) = false -> push q totreat; already_seen.(q) <- true; add_neighbour r
        | q::r -> add_neighbour r
    in

    while non_empty totreat do
        let s = pop totreat in
        already_seen.(s) <- true;
        (* we want to add s to the list lst *) s::lst;
        add_neighbour g.(s);
    done
in

(已经看到的是以前定义的布尔向量)

我唯一的问题是,我希望函数返回修改过的列表lst (在循环中),此时它是一个单元函数。

我试着把第一条定义为参考,但后来我不知道怎么回事.

我希望这更清楚,我现在对这一切并不熟悉.

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-13 11:32:40

下面是您代码的降级版本,它演示了一种实现您想要的功能的方法。

代码语言:javascript
复制
let non_empty _ = false

let dfs s lst =
  let local_lst = ref lst in

  while non_empty () do
    (*do stuff here*)
    let s = 1 in
    local_lst := s::!local_lst;
    (*do stuff here*)
  done;
  !local_lst

我首先将一个本地可变值local_lst初始化为作为参数给出的列表lst。然后在while循环中更新这个值。最后,我返回存储在local_lst中的值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50835562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档