gpt4 book ai didi

arrays - 在OCaml中制作int数组array类型的乘法表

转载 作者:行者123 更新时间:2023-12-02 06:57:57 25 4
gpt4 key购买 nike

我正在学习 OCaml 命令式编程的一些基础知识。

我正在尝试创建一个简单的 int 数组,其中包含乘法表,直到我作为参数传递的整数。

例如,表 2的输出预计返回

[|[|1;2|];[|2;4|]|]

我的代码不起作用。我首先初始化一个具有足够空间的数组并用零填充它。 x 的迭代适用于数组的索引,因为数组的每个条目都已填充,但 (x+1) * (y+1) 出现了问题部分。

表 2 的结果是 [|[|2;4|];[|2;4|]|],就好像它没有正确迭代一样x.

提供的答案有效。我不知道为什么——因为我们似乎在做同样的事情。我们用足够的空间初始化一个数组并用零填充它。然后我们使用嵌套的 for 循环来填充它。是因为答案使用的第一个 for 循环吗?为什么呢?

我的代码:

let table n =
let a = Array.make n (Array.make n 0) in
for x = 0 to n-1 do
for y = 0 to n-1 do
a.(x).(y) <- ((x+1) * (y+1));
done;
done;
a;;

答案:

let table n =
let a = Array.make n [||] in
for x = 0 to n-1 do
a.(x) <- Array.make n 0
done;
for y = 0 to n-1 do
for x = 0 to n-1 do
a.(x).(y) <- (x+1)*(y+1)
done
done;
a;;

最佳答案

您的问题是 Array.make 将使用相同的单个值填充数组。因此,您的外部数组不包含 n 个不同的数组,而是包含对同一数组的 n 个引用。

使用以下代码您会得到相同的不期望的结果:

let aa = Array.make n 0 in
let a = Array.make n [||] in
for x = 0 to n - 1 do
a.(x) <- aa
done

编写工作示例是为了避免此问题。首先,它创建一个包含空数组 [||]n 个副本的外部数组,然后用 n 不同的值填充它 通过为每个对象调用 Array.make 来创建数组对象。

要调整您的代码,您可以使用 Array.init 来代替,它为每个不同的数组元素调用指定的函数:

let a = Array.init n (fun _ -> Array.make n 0)

或者您可以使用Array.make_matrix:

let a = Array.make_matrix n n 0

更新

在示例中使用 ref 5 而不是 0 并不会真正改变任何内容,除了 ref 5 本身是可变的。假设我们不打算修改引用,而只是更改内部数组的内容。然后你会看到类似这样的内容:

# let a = Array.make 3 (Array.make 3 (ref 5));;
val a : int ref array array =
[|[|{contents = 5}; {contents = 5}; {contents = 5}|];
[|{contents = 5}; {contents = 5}; {contents = 5}|];
[|{contents = 5}; {contents = 5}; {contents = 5}|]|]
# a.(1).(2) <- ref 88;;
- : unit = ()
# a;;
- : int ref array array =
[|[|{contents = 5}; {contents = 5}; {contents = 88}|];
[|{contents = 5}; {contents = 5}; {contents = 88}|];
[|{contents = 5}; {contents = 5}; {contents = 88}|]|]

正如您所看到的,所有内部数组似乎都发生了变化。那是因为只有一个内部数组。所以实际上只有一个数组发生了变化。外部数组的所有 3 个元素中都包含该数组。

接下来,请注意,只有一次对 ref 5 的调用。这意味着所有引用(全部 9 个)都是相同的引用。您可以在下面看到这一点:

# let a = Array.make 3 (Array.make 3 (ref 5));;
val a : int ref array array =
[|[|{contents = 5}; {contents = 5}; {contents = 5}|];
[|{contents = 5}; {contents = 5}; {contents = 5}|];
[|{contents = 5}; {contents = 5}; {contents = 5}|]|]
# a.(1).(2) := 99;;
- : unit = ()
# a;;
- : int ref array array =
[|[|{contents = 99}; {contents = 99}; {contents = 99}|];
[|{contents = 99}; {contents = 99}; {contents = 99}|];
[|{contents = 99}; {contents = 99}; {contents = 99}|]|]

正如预期的那样,所有元素都更改为 99,因为只有一个引用出现在所有 9 个位置中。

如果您有其他想要解释的示例代码,可以将它们添加到上面。如果它们很复杂,最好发布一个新问题。

关于arrays - 在OCaml中制作int数组array类型的乘法表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38288221/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com