请考虑以下两个模块。模块a.ml包含:
(* Calls f with multi-indices ranging from beginning multi-index, args,
to the max multi-index (current arg is index). *)
let rec do_multi_call max_mindex ~f args index =
let dim = Array.length max_mindex in
if dim = 0 then
f args
else (
let rest = Array.sub max_mindex 1 (pred dim) in
args.(index) <- 0;
while (args.(index) <= max_mindex.(0)) do
do_multi_call rest ~f args (succ index);
args.(index) <- succ (args.(index));
done )
(* Calls f with m-indices ranging from 0 to max_mindex. *)
let multi_call (max_mindex : int array) ~f =
let n_indices = Array.length max_mindex in
let initial_args = Array.make n_indices 0 in
do_multi_call max_mindex f initial_args 0
模块b.ml包含:
open A
(* print int arrays *)
let print_index i =
Array.iter (Printf.printf "%d ") i;
print_endline ""; in
let d = [| 2 ; 3 |] in
let indices = Queue.create () in
let add_index i = (
print_index i;
Queue.add i indices) in
multi_call d add_index;
print_endline "";
Queue.iter print_index indices;
目标是生成从[| 0 ; 0 |]
到[| 2 ; 3 |]
的所有数组,并将其存储在indices
b.ml
中。但是,我得到的输出是
0 0
0 1
0 2
0 3
1 0
1 1
1 2
1 3
2 0
2 1
2 2
2 3
3 4
3 4
3 4
3 4
3 4
3 4
3 4
3 4
3 4
3 4
3 4
3 4
因此正确生成了数组,但我似乎无法将它们保存在某些数据结构中(队列indices
,这是输出中的第二组数字)。我也尝试使用list和refs,但我一直得到相同的结果。有人可以解释为什么会发生这种情况以及如何解决这个问题?感谢。
答案 0 :(得分:1)
在我看来,你在队列中多次添加相同的数组。当然,当您在最后打印时,您会看到同一阵列中的最终值打印多次。你需要制作数组的副本(因为它是一个可变的数据结构)。
查看问题的一种方法是观察您只创建一个数组(multi_call
),但是您要多次将其添加到队列中(在do_multi_call
中)。
<强>更新强>
这是一个(相对)简单的例子,它有同样的问题:
$ ocaml
OCaml version 4.02.1
# let m n =
let a = Array.make n 0 in
let res = Array.make n [| |] in
for i = 0 to n - 1 do
for j = 0 to n - 1 do a.(j) <- i done;
res.(i) <- a
done;
res;;
val m : int -> int array array = <fun>
# m 3;;
- : int array array = [|[|2; 2; 2|]; [|2; 2; 2|]; [|2; 2; 2|]|]
代码的(错误的)想法是使用a
来设置矩阵的每一行,然后将其存储在矩阵中。但是只有一个a
,所以矩阵的所有行实际上都是相同的单个数组。在OCaml中使用多维数组这是一个相当常见的错误。您的原始代码类似,但是使用队列而不是矩阵。