无法在 ocaml 中保存数组值
unable to save array values in ocaml
我正在编写一个简单的程序来计算 multiplication of two matrix。
(* matrix multiplication *)
let multiply_row_per_col (m1 : int array array) (m2 : int array array) =
(* create matrix *)
let nrows = get_num_rows m1 in
let ncols = get_num_rows m2 in
let matrix = create_matrix nrows ncols in
(* evaluation *)
for i = 0 to nrows - 1 do
for j = 0 to ncols - 1 do
let value = sum_row_col (get_row m1 i) (get_col m2 j) in
Printf.printf "%i,%i -> %i " i j value;
matrix.(i).(j) <- value;
Printf.printf "%i\n" matrix.(i).(j);
done;
done;
(* return value *)
matrix
;;
但它不能正常工作:矩阵的最后一行是正确的,所有其他行都包含最后一行的值。
utop # matrix;;
- : int array array = [|[|1; 2; 3|]; [|4; 5; 6|]; [|7; 8; 9|]|]
utop # multiply_row_per_col matrix matrix ;;
0,0 -> 30 30
0,1 -> 36 36
0,2 -> 42 42
1,0 -> 66 66
1,1 -> 81 81
1,2 -> 96 96
2,0 -> 102 102
2,1 -> 126 126
2,2 -> 150 150
- : int array array =
[|[|102; 126; 150|]; [|102; 126; 150|]; [|102; 126; 150|]|]
正确的结果应该是:
如您所见,单个值是正确的,但我无法将它们保存在矩阵中。你有什么想法吗?
这是在 utop
中执行的代码和一些测试,没有使用其他库(既不是 Core 也不是 Batteries):
(* 3x3 matrix *)
let matrix = [|
[| 1; 2; 3|];
[| 4; 5; 6|];
[| 7; 8; 9|]
|];;
(* return the cell of the matrix at [i][j] position *)
let get_cell (matrix : int array array) (row : int) (col : int) : int =
Array.get (Array.get matrix row) col
;;
(* return the n-th row *)
let get_row (matrix : int array array) (n : int) : int array =
Array.get matrix n
;;
(* return the n-th col of the matrix *)
let get_col (matrix : int array array) (n : int) : int array =
Array.map (fun row -> Array.get row n) matrix
;;
(* return the number of rows of a matrix *)
let get_num_rows matrix =
Array.length matrix
;;
(* return the number of cols of a matrix *)
let get_num_cols matrix =
Array.length (Array.get matrix 0)
;;
(* create NxM matrix *)
let create_matrix rows cols =
Array.make rows (Array.make cols 0)
;;
(* multiply each position of row and col, then sum all of them *)
let sum_row_col (row : int array) (col : int array) : int =
Array.fold_left (+) 0 (Array.map2 ( * ) row col)
;;
(* matrix multiplication *)
let multiply_row_per_col (m1 : int array array) (m2 : int array array) =
(* create matrix *)
let nrows = get_num_rows m1 in
let ncols = get_num_rows m2 in
let matrix = create_matrix nrows ncols in
(* evaluation *)
for i = 0 to nrows - 1 do
for j = 0 to ncols - 1 do
let value = sum_row_col (get_row m1 i) (get_col m2 j) in
Printf.printf "%i,%i -> %i " i j value;
matrix.(i).(j) <- value;
Printf.printf "%i\n" matrix.(i).(j);
done;
done;
(* return value *)
matrix
;;
(*
utop # #use "Matrix_multiplication.ml";;
val matrix : int array array = [|[|1; 2; 3|]; [|4; 5; 6|]; [|7; 8; 9|]|]
val get_cell : int array array -> int -> int -> int = <fun>
val get_row : int array array -> int -> int array = <fun>
val get_col : int array array -> int -> int array = <fun>
val get_num_rows : 'a array -> int = <fun>
val get_num_cols : 'a array array -> int = <fun>
val create_matrix : int -> int -> int array array = <fun>
val sum_row_col : int array -> int array -> int = <fun>
val multiply_row_per_col :
int array array -> int array array -> int array array = <fun>
─( 14:54:52 )─< command 42 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # get_cell matrix 0 0;;
- : int = 1
─( 14:55:12 )─< command 43 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # get_cell matrix 2 2;;
- : int = 9
─( 14:56:52 )─< command 45 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # get_row matrix 1;;
- : int array = [|4; 5; 6|]
─( 14:57:02 )─< command 46 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # get_col matrix 1;;
- : int array = [|2; 5; 8|]
─( 14:57:08 )─< command 47 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # create_matrix 3 3;;
- : int array array = [|[|0; 0; 0|]; [|0; 0; 0|]; [|0; 0; 0|]|]
─( 14:57:19 )─< command 48 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # sum_row_col [|1;2;3|] [|1;2;3|] ;;
- : int = 14
─( 14:57:31 )─< command 49 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # sum_row_col [|1;2;3|] [|1;4;7|] ;;
- : int = 30
─( 14:57:51 )─< command 50 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # multiply_row_per_col matrix matrix ;;
0,0 -> 30 30
0,1 -> 36 36
0,2 -> 42 42
1,0 -> 66 66
1,1 -> 81 81
1,2 -> 96 96
2,0 -> 102 102
2,1 -> 126 126
2,2 -> 150 150
- : int array array =
[|[|102; 126; 150|]; [|102; 126; 150|]; [|102; 126; 150|]|]
*)
问题出在您的 create_matrix
函数中。它目前所做的是创建 one 数组并为每一行使用相同的数组。这意味着在 mat.(2).(2)
中写入与在 mat.(1).(2)
中写入相同。
stdlib 中有一个为此目的而创建的函数:Array.make_matrix
,请使用它。 ;)
我正在编写一个简单的程序来计算 multiplication of two matrix。
(* matrix multiplication *)
let multiply_row_per_col (m1 : int array array) (m2 : int array array) =
(* create matrix *)
let nrows = get_num_rows m1 in
let ncols = get_num_rows m2 in
let matrix = create_matrix nrows ncols in
(* evaluation *)
for i = 0 to nrows - 1 do
for j = 0 to ncols - 1 do
let value = sum_row_col (get_row m1 i) (get_col m2 j) in
Printf.printf "%i,%i -> %i " i j value;
matrix.(i).(j) <- value;
Printf.printf "%i\n" matrix.(i).(j);
done;
done;
(* return value *)
matrix
;;
但它不能正常工作:矩阵的最后一行是正确的,所有其他行都包含最后一行的值。
utop # matrix;;
- : int array array = [|[|1; 2; 3|]; [|4; 5; 6|]; [|7; 8; 9|]|]
utop # multiply_row_per_col matrix matrix ;;
0,0 -> 30 30
0,1 -> 36 36
0,2 -> 42 42
1,0 -> 66 66
1,1 -> 81 81
1,2 -> 96 96
2,0 -> 102 102
2,1 -> 126 126
2,2 -> 150 150
- : int array array =
[|[|102; 126; 150|]; [|102; 126; 150|]; [|102; 126; 150|]|]
正确的结果应该是:
这是在 utop
中执行的代码和一些测试,没有使用其他库(既不是 Core 也不是 Batteries):
(* 3x3 matrix *)
let matrix = [|
[| 1; 2; 3|];
[| 4; 5; 6|];
[| 7; 8; 9|]
|];;
(* return the cell of the matrix at [i][j] position *)
let get_cell (matrix : int array array) (row : int) (col : int) : int =
Array.get (Array.get matrix row) col
;;
(* return the n-th row *)
let get_row (matrix : int array array) (n : int) : int array =
Array.get matrix n
;;
(* return the n-th col of the matrix *)
let get_col (matrix : int array array) (n : int) : int array =
Array.map (fun row -> Array.get row n) matrix
;;
(* return the number of rows of a matrix *)
let get_num_rows matrix =
Array.length matrix
;;
(* return the number of cols of a matrix *)
let get_num_cols matrix =
Array.length (Array.get matrix 0)
;;
(* create NxM matrix *)
let create_matrix rows cols =
Array.make rows (Array.make cols 0)
;;
(* multiply each position of row and col, then sum all of them *)
let sum_row_col (row : int array) (col : int array) : int =
Array.fold_left (+) 0 (Array.map2 ( * ) row col)
;;
(* matrix multiplication *)
let multiply_row_per_col (m1 : int array array) (m2 : int array array) =
(* create matrix *)
let nrows = get_num_rows m1 in
let ncols = get_num_rows m2 in
let matrix = create_matrix nrows ncols in
(* evaluation *)
for i = 0 to nrows - 1 do
for j = 0 to ncols - 1 do
let value = sum_row_col (get_row m1 i) (get_col m2 j) in
Printf.printf "%i,%i -> %i " i j value;
matrix.(i).(j) <- value;
Printf.printf "%i\n" matrix.(i).(j);
done;
done;
(* return value *)
matrix
;;
(*
utop # #use "Matrix_multiplication.ml";;
val matrix : int array array = [|[|1; 2; 3|]; [|4; 5; 6|]; [|7; 8; 9|]|]
val get_cell : int array array -> int -> int -> int = <fun>
val get_row : int array array -> int -> int array = <fun>
val get_col : int array array -> int -> int array = <fun>
val get_num_rows : 'a array -> int = <fun>
val get_num_cols : 'a array array -> int = <fun>
val create_matrix : int -> int -> int array array = <fun>
val sum_row_col : int array -> int array -> int = <fun>
val multiply_row_per_col :
int array array -> int array array -> int array array = <fun>
─( 14:54:52 )─< command 42 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # get_cell matrix 0 0;;
- : int = 1
─( 14:55:12 )─< command 43 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # get_cell matrix 2 2;;
- : int = 9
─( 14:56:52 )─< command 45 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # get_row matrix 1;;
- : int array = [|4; 5; 6|]
─( 14:57:02 )─< command 46 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # get_col matrix 1;;
- : int array = [|2; 5; 8|]
─( 14:57:08 )─< command 47 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # create_matrix 3 3;;
- : int array array = [|[|0; 0; 0|]; [|0; 0; 0|]; [|0; 0; 0|]|]
─( 14:57:19 )─< command 48 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # sum_row_col [|1;2;3|] [|1;2;3|] ;;
- : int = 14
─( 14:57:31 )─< command 49 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # sum_row_col [|1;2;3|] [|1;4;7|] ;;
- : int = 30
─( 14:57:51 )─< command 50 >─────────────────────────────────────────────────────────────────────────────{ counter: 0 }─
utop # multiply_row_per_col matrix matrix ;;
0,0 -> 30 30
0,1 -> 36 36
0,2 -> 42 42
1,0 -> 66 66
1,1 -> 81 81
1,2 -> 96 96
2,0 -> 102 102
2,1 -> 126 126
2,2 -> 150 150
- : int array array =
[|[|102; 126; 150|]; [|102; 126; 150|]; [|102; 126; 150|]|]
*)
问题出在您的 create_matrix
函数中。它目前所做的是创建 one 数组并为每一行使用相同的数组。这意味着在 mat.(2).(2)
中写入与在 mat.(1).(2)
中写入相同。
stdlib 中有一个为此目的而创建的函数:Array.make_matrix
,请使用它。 ;)