我想要一个数组从Fortran中的数组中删除某个索引值之后的所有行。这意味着,如果数组的大小最初为p,则它将变为q,其中q是将删除所有内容的索引。
有关代码如下:
real(8), allocatable :: circlesx(:),circlesy(:)
allocate(circlesx(n**2-n))
allocate(circlesy(n**2-n))
do i=1,n-1
do j=i+1,n
call intersect2circles(stlo(i),stla(i),distance(i),stlo(j),stla(j),distance(j),ax,ay,bx,by,flag)
if (flag==0) then
circlesx(k)=ax
circlesy(k)=ay
circlesx(k+1)=bx
circlesy(k+1)=by
k=k+2
endif
enddo
enddo
该标志基本上检查两个圆是否相交。因此,如果没有交集,则不会为数组circlesx
和circlesy
分配任何值。我首先分配的数组的大小是n个圆的交点的最大数量= n^2-n
。如果不分配它们,则会出现细分错误。
Reshape也没有用,尽管我在那儿做错了。这产生了无法分类的语句错误:-
reshape(circlesx,[ n**2-n-1 ])
我希望循环完成后,圈子数组的大小更改为k-2
所以我需要的是,如果n = 2,那么circlex和circley的大小为2,那么
circlesx=[0,0]
.
.
some calculations
.
.
circlesx=[1.2,0] ! only one value has been allocated
.
.
reshape the array accordingly
.
.
circlesx=[1.2]
在Fortran中有什么方法可以做到这一点?我正在使用f90文件扩展名并使用gfortran v7.3.0
答案 0 :(得分:5)
围绕数组动态调整大小的问题通常在乎扩大数组。那是更难的问题。 1
但是,基本的考虑是相同的。考虑
integer, allocatable :: arr(:)
allocate(arr(3))
arr = [1, 2, 3]
end
有了内在赋值,我们从其他地方看到我们可以写
integer, allocatable :: arr(:)
arr = [1, 2, 3]
end
,并将arr
分配给正确的形状作为分配的一部分。
我们已经看到它可以:扩大数组
arr = [arr, 4]
删除“不良值”:
arr = PACK(arr, arr>1.and.arr<4)
仅选择前几个元素就很简单
arr = arr(:q)
编译器需要特殊标志来正确编译此类代码的日子正在慢慢过去,但确实(特别是如果使用旧版本的话)请查看编译器文档以了解如何确保自动分配在固有分配上发生。
1 即使在没有动态内存分配的日子里,也可以简单地处理“较短”的数组。取一个您需要的静态大小的数组,并对使用了多少个元素进行簿记。在现代代码中,使用旧库时可能会看到这种伪像。