我遇到以下问题:
我想循环一个特定的数字序列,例如
1 3 4 6 7 9 10 .... 528
我想过要办法,但我对fortran并不熟悉。我们的想法是创建一个列表,其中的数字不在序列中:
B=(/2 5 8 11 .... 527/)
并从包含所有数字
的另一个列表推导出此列表A=(/1 2 3 4 5 6 7 8 9 10 11 ..... 528/)
C=A-B
我在想的是:
program test
implicit none
integer, dimension(6) :: A
integer, dimension(10) :: B
integer :: i, j
A = (/ 1 2 3 4 5 6 7 8 9 10 11 ..... 528/)
B = (/ 2 5 8 11 .... 527/)
C=A-B
end program test
这是正确的方法吗?如果是,我如何推断出两个列表?
答案 0 :(得分:3)
根据您提出的问题A
和B
,您可以先声明一个logical
数组并设置其所有元素.true.
,即:
logical, dimension(size(A)) :: themask = .true.
然后是表达式
themask(B) = .false.
将设置为.false.
索引向量中themask
的所有元素B
和
C = pack(A,themask)
将仅在C
中返回A
中themask
中相应元素为.true.
的{{1}}元素。为此,你必须像这样声明C
:
integer, dimension(:), allocatable :: C
并使用符合Fortran 2003标准的编译器,该编译器允许自动分配。目前大多数广泛使用的编译器都实现了这一功能。
除了保存A
整数列表之外,如果你没有使用N
,那么你可以使用临时工作
C = pack([(ix, ix = 1,N)],themask)
其中ix
是先前声明的整数。此表达式 - [(ix, ix = 1,N)]
- 使用隐含做循环来填充临时向量。
如果这是您想要做的事情,您现在可以遍历C
的值,但是您可能希望将C
用作另一个rank-1数组的向量索引,例如{ {1}}。
这里没有摆弄循环,但我没有声称这种方法比@francescalus的基于循环的建议表现更好(或更差或更差)。
答案 1 :(得分:2)
您的-
不是一个集合补码运算符,因此C=A-B
不会返回一个数组(您尚未声明),该数组由A中的值而不是B组成。
但是,您不需要为了您的愿望而这样做:
do i=1, 528
if (....) ! i not in B
....
end do
当然,棘手的部分是if
条件。但是,如果B被排序:
j = 1
do i=1, 528
if (i.eq.B(j)) then
j = j+1
cycle
end if
...
end do