我有一堆不同长度的数组,它们都类似于a1 = [1.0]
等a2 = [1.0,2.0]
。我需要遍历函数中的所有数组并使用它们的元素执行操作,但它们都不是索引的函数。我想知道在 Fortran 95 中这样做的最佳方法是什么?我认为您可以制作一个维度数组(max_length, max_length)
,然后将它们全部放入其中;这将允许您通过索引引用每个元素,但它会浪费空间,并且每次调用它时都必须将函数传递给整个数组,而不仅仅是单个数组(我实际上不知道是否很重要,但似乎会。)
2 回答
拥有 (maxlen, maxlen) 的数组只会在您谈论 (thousands,数千) 时造成麻烦,否则这只是一种低效的方法。
假设您的数组都是相同的类型和相同的维数,那么您可以创建一个派生类型来保存您的数组,然后创建一个您刚刚创建的类型的数组。因此,您将拥有一个可变长度数组的数组。
type arrays
integer(kind=8):: length !optional but very helpfull
integer(kind=8), dimension(:), allocatable:: a
end type arrays
现在您可以声明您的类型数组数组:
type(arrays), dimension(:), allocatable:: arrayList
type(arrays):: arrayList ( 1000 ) !if you know beforehand how many arrays you need
这种方法有两点需要注意:
- 以我的经验,遍历派生类型的数组比遍历本机类型数组要慢。
- 现在您可以访问您的 a1、a2,因为
arrayList(i) % a(j)
它一见钟情
资料来源:http ://courses.physics.illinois.edu/phys466/comp_info/derived.html
有关其他信息,您可以访问Fortran Wiki,这是一个非常好的来源。
答案实际上取决于您的实际情况。如果各种数组的长度不相同,但至少在相同的数量级上,那么使用一个数组来处理所有数组可能会更好。但是,您将需要一个额外的数组,该数组给出每个数组的元素数。您的功能可能看起来像:
module test
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
subroutine process(array, nelems)
real(dp), intent(in) :: array(:,:)
integer, intent(in) :: nelems(:)
integer :: ii, jj
do ii = 1, size(arrays(dim=2))
do jj = 1, nelems(ii)
! Do something with element jj of array ii.
end do
end do
end subroutine process
end module test
其中子array(1:nelems(ii),ii)
数组存储第 i 个一维数组的元素。
以下几点可能值得注意:
您应该将 1D 子阵列按列排列在集体 2D 阵列中,以便子阵列在内存中是连续的。
您只需将两个数组而不是一堆数组传递给子例程。这应该给出更清晰的代码。
当然,您会浪费一些内存,因为集体数组的形状必须是
(max_nr_of_elements_in_an_array, number_of_arrays)
. 如果数组长度非常不同,并且您确实有很多数组,因此浪费的内存变得很重要,您可以考虑 Eudoardo 建议的数组数组方法。但是,这通常比直接方法慢,因为单个数组分散在内存中(缓存有问题)。