3

问题的简化描述:

商店里正好有maxSize人在购物。他们每个人都有一个购物清单,其中包含项目的价格(作为整数)。使用 Fortran 数组,我如何表示所有购物清单。购物清单可以包含任意数量的项目(1、10、1000000000)。

(注意:实际问题要复杂得多。甚至与购物无关。)

懒惰的方法是:

integer :: array(maxSize, A_REALLY_BIG_NUMBER)

不过这样很浪费,我基本上是想让第二个维度是可变的,然后分别给每个人分配。

显而易见的尝试,注定要失败:

integer, allocatable :: array(:,:)
allocate(array(maxSize, :)) ! Compiler error

Fortran 似乎要求数组在每个维度上都有固定的大小。

这很奇怪,因为大多数语言将多维数组视为“数组数组”,因此您可以单独设置“数组数组”中每个数组的大小。

这是有效的方法

type array1D
    integer, allocatable :: elements(:) ! The compiler is fine with this!
endtype array1D

type(array1D) :: array2D(10)
integer :: i

do i=1, size(array2D)
    allocate(array2D(i)%elements(sizeAt(i))
enddo

如果这是唯一的解决方案,我想我会使用它。但我有点希望有一种方法可以使用内在函数来做到这一点。必须为这样一个简单的事情定义自定义类型有点烦人。

在 C 中,由于数组基本上是一个语法奇特的指针,因此您可以使用指针数组来做到这一点:

int sizeAt(int x); //Function that gets the size in the 2nd dimension
int * array[maxSize];

for (int x = 0; x < maxSize; ++x)
        array[x] = (int*)(calloc(sizeAt(x) , sizeof(int)));

Fortran 似乎也有指针。但是我发现的唯一教程都说“永远不要使用这些”或类似的东西。

4

1 回答 1

8

您似乎在抱怨 Fortran 不是 C。这是真的。标准委员会选择以不同方式做事的原因可能有无数个,但这里有一些想法:

Fortran 数组的强大功能之一是它们可以被切片。

a(:,:,3) = b(:,:,3)

是一个完全有效的陈述。 如果数组是“指向数组的指针数组”,则无法实现这一点,因为沿每个轴的尺寸不一定一致(您要实现的正是这种情况)。

在 C 中,确实没有多维数组这样的东西。您可以使用指向数组的指针数组来实现看起来相似的东西,但这并不是真正的多维数组,因为它不共享公共内存块。这可能会影响性能。事实上,在 HPC(许多 Fortran 用户花费时间)中,多维 C 数组通常是包裹在宏中的一维数组,用于根据维度的大小计算步幅。此外,像这样取消引用 7D 数组:

a[i][j][k][l][m][n][o]

比以下内容更难输入:

a(i,j,k,l,m,n,o)

最后,您发布的解决方案最接近您尝试模拟的 C 代码——它有什么问题?请注意,对于您的问题陈述,可能需要更复杂的数据结构(如链表)(可以在 C 或 Fortran 中实现)。当然,就性能而言,链表是最差的,但如果这不是问题,它可能是作为“购物者”使用的正确数据结构,可以决定将更多东西添加到他们的“购物车”中,即使它不在他们带到商店的购物清单上。

于 2012-06-09T14:58:34.183 回答