在Fortran列表中输入一系列数字

时间:2014-01-28 09:20:22

标签: fortran fortran90

我遇到以下问题:

我想循环一个特定的数字序列,例如

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

这是正确的方法吗?如果是,我如何推断出两个列表?

2 个答案:

答案 0 :(得分:3)

根据您提出的问题AB,您可以先声明一个logical数组并设置其所有元素.true.

logical, dimension(size(A)) :: themask = .true.

然后是表达式

themask(B) = .false.

将设置为.false.索引向量中themask的所有元素B

C = pack(A,themask)

将仅在C中返回Athemask中相应元素为.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