在Python中:
def select(x):
y = []
for e in x:
if e!=0:
y.append(e)
return y
其作用如下:
x = [1,0,2,0,0,3] select(x) [1,2,3]
翻译成Fortran:
function select(x,n) result(y)
implicit none
integer:: x(n),n,i,j,y(?)
j = 0
do i=1,n
if (x(i)/=0) then
j = j+1
y(j) = x(i)
endif
enddo
end function
问题在Fortran中:
对于1,如果定义为y(n),则输出为:
x = (/1,0,2,0,0,3/) print *,select(x,6) 1,2,3,0,0,0
这是不需要的!
!-------------------------------
评论:
1-所有给出的答案在本文中都很有用。特别是M.S.B和eryksun'S.
2-我试图根据我的问题调整思路,并使用F2Py
进行编译,但没有成功。我已经用GFortran调试了它们,所有的都成功了。它可能是F2Py
中的一个错误,或者是一些我不知道如何正确使用它的东西。我会试着在另一篇文章中报道这个问题。
更新: 可以在here找到一个链接的问题。
下面是一个Fortran函数返回可变长度数组的示例。这是Fortran 2003的一个特性。测试驱动程序中还使用了另一个Fortran 2003特性自动分配任务。
这里有一个替代的解决方案,它使用一个临时数组来根据需要“增长”输出数组(函数返回)。虽然避免了两次通过输入数组,但需要数组副本。Fortran 2003的另一个特性move_alloc减少了所需的副本数量。move_alloc还负责输出数组(此处为“y”)的(重新)分配和输入数组的释放(此处为“temp”)。也许这更优雅,但由于使用了多个副本,因此效率可能更低。这个版本可能更具教育性,而不是实用性。@eryksun的版本使用一个pass和一个copy,代价是使临时数组达到最大。
我希望有一个真正的Fortran程序员出现,但是在没有更好的建议的情况下,我只指定
x(:)
的形状而不是大小,使用临时数组temp(size(x))
,并使输出为yallocatable
。然后在第一次传递之后,allocate(y(j))
并从临时数组中复制值。但是我不能强调我不是一个Fortran程序员,所以我不能说这个语言是否有一个可增长的数组,或者是否有一个用于后者的库。编辑:
根据M.S.B.的回答,这里有一个函数的修订版本,它在过度分配的情况下增长了
tempy
。就像它在末尾将结果复制到y一样。事实证明,我不需要显式地以最终大小分配新数组。相反,它可以通过赋值自动完成。如果您问题中的示例确实是您想要做的,那么可以使用Fortran90内部“pack”:
示例程序的输出为:1 2 3
相关问题 更多 >
编程相关推荐