Ocaml中的数组操作

时间:2016-11-11 14:24:12

标签: arrays ocaml combinatorics

我正在尝试在Ocaml中执行Array的所有组合。 我正在尝试做一个递归函数,它返回一个数组,它的初始状态需要是let a = [|0;0;0|],我需要像第一次迭代中那样递归地改变它需要a = [|1;0;0|]和下一个a = [|0;1;0|] a = [|1;1;1|] 1}}依此类推,直到达到void MoveRight(int *a,int n, int startIndex) { int j,temp; j=n-1; for(int i=startIndex;i<n;i++) { temp = a[j]; a[j]=a[i]; a[i]=temp; } } void InsertionSort(int *a,int n) { int i,number,j; printf("Enter %d numbers for the array\n",n); for(i=0;i<n;i++) { scanf("%d",&number); for(j=0;j<=i;j++) { if(number<a[j]) { MoveRight(a,n,j); a[j]=number; break; } } } } 所有可能的组合,因此在这种情况下需要进行2 ^ 3次更改。 我知道我不是很明确,但我有点难以解释,但如果有人能帮助我,我会很感激。

2 个答案:

答案 0 :(得分:2)

数组是一个可变数据结构,因此,如果您要在每次递归调用中对其进行变异,那么将采用该变异。基本上,这意味着,在2^3调用之后,数组的状态将是最后一个组合。所以,完全没有必要这样做。一个有效的解决方案是创建一个函数,它将采用一个初始数组,并返回所有组合的列表。更有效的解决方案是编写一个函数,该函数将采用另一个函数,并将其应用于所有组合(或折叠所有组合)。这样可以节省内存,因为您不需要存储所有组合。

大纲是实现以下界面:

type state
val zero : state
val next : state -> state option
val value : state -> int array

其中state将是一个游标,它将在组合空间中移动。它可以是整数或整数数组,也可以是其他任何数组。实现这些功能后,您可以按如下方式轻松实现您的功能:

let fold_combinations f init = 
  let rec fold state x = 
     let x = f (value state) x in
     match next state with
     | None -> x
     | Some state -> fold state x in
  fold zero init

最后,您的示例不是显示所有可能的组合或排列,而是显示位宽等于输入数组长度的所有可能二进制值。如果这确实是您要解决的任务,那么您只需将整数转换为二进制表示即可。在这种情况下,state的良好选择是int,然后next函数是一个增量,它将停留在2^k-1,其中k是初始状态的长度。 value函数只是将一个整数转换为位数组,其中n位(元素)可以确定为state land (1 lsl n)。您可以使用Array.init每次创建一个全新的数组,或者,您可以遍历现有数组。这将更有效,但容易出错。

答案 1 :(得分:-1)

let combinaison f n =
  let rec aux acc n =  
    if n=0 then List.iter f acc
    else (
      aux (List.map (fun l -> 0::l  ) acc) (n-1);  
      aux (List.map (fun l -> 1::l  ) acc) (n-1);  
    )
  in
  aux [[]] n
;; 

测试

combinaison ( fun lx -> 
  let a=Array.of_list lx in
  Array.iter ( fun x ->
    Printf.printf "%d " x
  ) a ;
  Printf.printf "\n"
) 3;;

0 0 0 
1 0 0 
0 1 0 
1 1 0 
0 0 1 
1 0 1 
0 1 1 
1 1 1