生成两个值(OCaml或其他语言)之间给定长度的所有列表

时间:2014-11-16 14:57:41

标签: ocaml

我是ocaml的新手并尝试编写一些代码来生成两个值之间的所有数字列表。

例如,如果我调用此函数generate,我想获得类似这样的内容:

let generate ~min ~max ~length (* Maybe other arguments *) =
    (* The code *)
;;

generate ~min:0 ~max:3 ~length:4;;

应该返回

[
[0;0;0];
[1;0;0];
[2;0;0];
[3;0;0];
[0;1;0];

等等,

[3;2;3];
[0;3;3];
[1;3;3];
[2;3;3];
[3;3;3];
]

我已经尝试过这样的代码:

open Core.Std;;

type next_list =
    | Complete of int list
    | Partial of int list
    | Result of (int array) list
;;

let rec next ~r ~min ~max ~l =
    let detox = function | Partial a -> a | _ -> assert false in
    match l with
    | Partial (hd :: tl) when hd <= max -> Partial (hd + 1 :: tl)
    | Partial (hd :: tl) when hd = max + 1 -> next ~r ~min ~max
    ~l:(Partial (min :: (detox (next ~r ~min ~max ~l:(Partial tl))) ))
    | Complete (hd :: tl) when hd <= max -> next ~r:([l] :: r) ~min ~max
    ~l:(Complete (hd + 1 :: tl))
    | Complete (hd :: tl) when hd = max + 1 -> next ~r ~min ~max
    ~l:(Complete (min :: (detox (next ~r ~min ~max ~l:(Partial tl)))))
    (*| Partial [] -> next ~r ~min ~max ~l:(Result r)*)
    | Result a -> Result a

如果需要,它可以分散在几个功能周围,这不是问题 我也对非ocaml代码或想法感兴趣。

感谢您的帮助。

这是我关于Stackoverflow的第一个问题,如果我的问题不清楚,请不要犹豫。

2 个答案:

答案 0 :(得分:1)

这里有一些解决方案: 首先,我们定义需要2个列表l1&amp; l2作为输入并产生一个列表列表,其中每个元素是由l1的1个元素增加的l2:

 let enumerate l ll = List.fold ~init:[] ~f:(fun op x -> (x::ll)::op) l;;

枚举[0; 1; 2; 3] [4; 5; 6] ;; - :int list list = [[3; 4; 5; 6]; [2; 4; 5; 6]; [1; 4; 5; 6]; [0; 4; 5; 6]]

现在生成:

   let rec generate length ll =
     if length=1 then List.fold ~init:[] ~f:(fun op x -> [x]::op) ll
     else 
       let result = generate (length-1) ll in
       List.fold ~init:[] ~f:(fun op x -> (enumerate ll x)@op) result;;

用法如下:

generate 2 [1;2;3];; (* instead of generate ~min:1 ~max:3 ~length:2 *)

一些解释: List.fold~init:[] ~f :(有趣的op x - &gt; [x] :: op)ll =&GT;这将创建列表的初始列表(单例)

第二个:获取每个长度为-1的列表并执行枚举。

答案 1 :(得分:0)

这里有一个提示:

let count_prefix low high lists =
  ???

let generate min max length =
  let rec recur low high len =
    if len = 0 then []
    else count_prefix low high (recur low high (len - 1)) in
  recur min max length

count_prefix应该返回一个列表,该列表是lists的前缀为数字lowhigh的元素。如果lists为空,则应返回包含数字lowhigh的列表列表。那就是:

count_prefix 0 3 [] => [[0]; [1]; [2]]
count_prefix 0 3 [[10];[20]] => [[0; 10]; [0; 20]; [1; 10]; [1; 20]; [2; 10]; [2; 20]]

填写count_prefix

的定义