OCaml:计算对列表中的不同值

标签 ocaml

我有一个配对列表

let myList=[(0,1);(0,2);(0,3);(1,5);(2,4);(3,5);(5,4);(5,6);(4,3)];;

为了计算列表中存在的每个单独的不同值,我有这个过程

let rec flat lst  visited =
match lst with
[]->visited
| (x,y)::xs -> flat xs (x::y::visited)) ;;


let newLst = flat myList [];;

val newLst : int list =
  [4; 3; 5; 6; 5; 4; 3; 5; 2; 4; 1; 5; 0; 3; 0; 2; 0; 1]

let rec count lista = 
match lista with  
[]->0
| x::xs -> 
if (List.mem x xs) then count xs
else 1+count xs;;

count newLst;;
- : int = 7

代码运行正确,但我的问题是:

有没有更优雅或更有效的方法来做到这一点? 例如一个独特的功能而不是两个

最佳答案

您的方法有效,简单易懂。它唯一的缺点是您的代码使用了 Shlemiel the painter's algorithm .这意味着,处理时间表现为列表大小的二次函数。

如果要去掉,用sets比较合适:将列表中的所有数字添加到一个集合中并计算其大小。现在时间性能在 n log(n) 中并且扩展性更好。

let myList=[(0,1);(0,2);(0,3);(1,5);(2,4);(3,5);(5,4);(5,6);(4,3)]

module IntegerSet = Set.Make(struct
    type t = int
    let compare = Pervasives.compare
  end)

let count lst0 =
  let rec loop acc lst =
    match lst with
    | [] -> IntegerSet.cardinal acc
    | (a,b)::tl -> loop IntegerSet.(add b (add a acc)) tl
  in
  loop IntegerSet.empty lst0

这段代码使用了一个累加器acc,它通过迭代来填充 在名单之上。读取完所有列表后,返回累加器中的元素数。

关于OCaml:计算对列表中的不同值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34960999/

相关文章:

ocaml - 有没有办法打印用户定义的数据类型?

ocaml - 平方和的总和 OCaml

stack - Ocaml 堆栈推送会产生类型错误

ubuntu - 在 Manjaro 上使用 OCaml 版本 4.08.1 编译 unison 2.48.4 版本

安装tcoq时OCaml和预处理器有不兼容的版本错误

list - 如何在 OCaml 中编写列表?

oop - 如何强制仅调用父类(super class)的方法,尽管它们已被重写(在 Ocaml 中)

由于类型的专门递归使用而导致的 ocaml 类型过度绑定(bind)

functional-programming - ocaml编译过程的逻辑

haskell - SystemT 编译器和处理 Haskell 中的无限类型