OCaml-从一维数组到二维数组的转换
我试图在OCaml中将一维数组转换为二维数组 在测试我编写的函数时:OCaml-从一维数组到二维数组的转换,ocaml,Ocaml,我试图在OCaml中将一维数组转换为二维数组 在测试我编写的函数时: # to_array2d [|1;2;3;1;2;4;1;2;5|];; 我得到了不正确的结果: int array array = [|[|1; 2; 5|]; [|1; 2; 5|]; [|1; 2; 5|]|] 正确的结果应该是: int array array = [|[|1; 2; 3|]; [|1; 2; 4|]; [|1; 2; 5|]|] 代码如下: let to_array2d (array1d: in
# to_array2d [|1;2;3;1;2;4;1;2;5|];;
我得到了不正确的结果:
int array array = [|[|1; 2; 5|]; [|1; 2; 5|]; [|1; 2; 5|]|]
正确的结果应该是:
int array array = [|[|1; 2; 3|]; [|1; 2; 4|]; [|1; 2; 5|]|]
代码如下:
let to_array2d (array1d: int array) : int array array =
let dim = int_of_float (sqrt (float (Array.length array1d))) in
let array2d = Array.make dim (Array.make dim 0 ) in
for i = 0 to (dim - 1) do
for j = 0 to (dim - 1) do
array2d.(i).(j) <- (Array.get array1d (i * dim + j))
done
done;
array2d
;;
let to_array2d(array1d:int数组):int数组=
设dim=in中浮点(sqrt(float(Array.length array1d))的整数
将array2d=Array.make dim(Array.make dim 0)放入
对于i=0至(尺寸-1)do
对于j=0至(尺寸-1)do
array2d.(i)。(j)您创建的二维数组不正确Array.make
将只复制第二个参数dim
次。因此,您有一个指向同一数组的三个指针的数组。查看有关如何正确烹饪数组的更多详细信息。使用Array.init
函数可以更好地编写您的特定案例
let to_array2d (array1d: int array) : int array array =
let dim = int_of_float (sqrt (float (Array.length array1d))) in
Array.init dim (fun i -> Array.init dim (fun j -> array1d.(i * dim + j)))
尽管如此,我不喜欢sqrt
ing长度的想法
关于这个问题的一个很好的解释可以在中找到。请参阅第68页(pdf第94页)。您创建的二维阵列不正确Array.make
将只复制第二个参数dim
次。因此,您有一个指向同一数组的三个指针的数组。查看有关如何正确烹饪数组的更多详细信息。使用Array.init
函数可以更好地编写您的特定案例
let to_array2d (array1d: int array) : int array array =
let dim = int_of_float (sqrt (float (Array.length array1d))) in
Array.init dim (fun i -> Array.init dim (fun j -> array1d.(i * dim + j)))
尽管如此,我不喜欢sqrt
ing长度的想法
关于这个问题的一个很好的解释可以在中找到。查看第68页(pdf第94页)。详细说明@ivg的答案:数组。make
将获取您给定的值,并将其放入新数组的所有元素中。对于具有结构的值(如数组),这意味着您最终将出现三次相同的值
要详细说明@ivg的答案:Array.make
将获取您给它的值,并将其放入新数组的所有元素中。对于具有结构的值(如数组),这意味着您最终将出现三次相同的值
代码中的错误位置是
let b =
Array.make dim (Array.make dim 0)
这不是你想要的。名称b
不在代码中,但便于讨论。为了理解您看到的内容,让我们以以下等效方式重写此代码:
let b =
let a = Array.make dim 0 in
Array.make dim a
此代码生成一个长度为dim
的数组,其条目均为a
。这些不是a
的副本,它们只是a
的不同名称。用OCaml表示这一点的正确方法是说这些结构在物理上是相等的,=
操作符测试物理上的相等性
# b.(0) == b.(1);;
true
物理相等是比更常见的=
运算符测试的结构相等更强的关系。规定,给定两个物理上相等的可变结构,如b.(0)
和b.(1)
,对其中任何一个结构的修改也会影响另一个结构,或者换句话说:
val(=):'a->'a->bool
e1==e2
测试e1
和e2
的物理相等性。对于可变类型,如引用、数组、字节序列、具有可变字段的记录和具有可变实例变量的对象,e1==e2
为真,当且仅当e1
的物理修改也影响e2
。在不可变类型上,(==)
的行为依赖于实现;但是,可以保证e1==e2
意味着比较e1 e2=0
我们可以把这看作是一种正式的说法,即这两种结构“实际上是相同的”
如果您想调整代码的结构,可以利用数组。make_matrix
函数生成新的二维数组。如果您厌倦了调试for循环中的错误,可以使用更为ocaml ish的解决方案:
let unpack dim a =
let line i =
Array.init dim (fun j -> a.(i*dim + j))
in
Array.init dim line
let to_array2d a =
let dim = int_of_float (sqrt (float (Array.length array1d))) in
unpack dim a
另请参见
代码中的错误位置是
let b =
Array.make dim (Array.make dim 0)
这不是你想要的。名称b
不在代码中,但便于讨论。为了理解您看到的内容,让我们以以下等效方式重写此代码:
let b =
let a = Array.make dim 0 in
Array.make dim a
此代码生成一个长度为dim
的数组,其条目均为a
。这些不是a
的副本,它们只是a
的不同名称。用OCaml表示这一点的正确方法是说这些结构在物理上是相等的,=
操作符测试物理上的相等性
# b.(0) == b.(1);;
true
物理相等是比更常见的=
运算符测试的结构相等更强的关系。规定,给定两个物理上相等的可变结构,如b.(0)
和b.(1)
,对其中任何一个结构的修改也会影响另一个结构,或者换句话说:
val(=):'a->'a->bool
e1==e2
测试e1
和e2
的物理相等性。对于可变类型,如引用、数组、字节序列、具有可变字段的记录和具有可变实例变量的对象,e1==e2
为真,当且仅当e1
的物理修改也影响e2
。在不可变类型上,(==)
的行为依赖于实现;但是,可以保证e1==e2
意味着比较e1 e2=0
我们可以把这看作是一种正式的说法,即这两种结构“实际上是相同的”
如果您想调整代码的结构,可以利用数组。make_matrix
函数生成新的二维数组。如果您厌倦了调试for循环中的错误,可以使用更为ocaml ish的解决方案:
let unpack dim a =
let line i =
Array.init dim (fun j -> a.(i*dim + j))
in
Array.init dim line
let to_array2d a =
let dim = int_of_float (sqrt (float (Array.length array1d))) in
unpack dim a
另请参见