【问题标题】:Input a sequence of numbers in a Fortran list在 Fortran 列表中输入数字序列
【发布时间】:2014-02-19 12:08:46
【问题描述】:

我面临以下问题:

我想遍历特定的数字序列,例如

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

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

【问题讨论】:

    标签: fortran fortran90


    【解决方案1】:

    鉴于AB 如您的问题所示,您可以首先声明一个logicals 数组并设置其所有元素.true.ie

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

    然后是表达式

    themask(B) = .false.
    

    将索引向量Bthemask的所有元素设置为.false.

    C = pack(A,themask)
    

    将在C 中仅返回Athemask 中对应元素为.true. 的那些元素。为此,您必须像这样声明C

    integer, dimension(:), allocatable :: C
    

    并使用允许自动分配的 Fortran 2003 兼容编译器。目前大多数广泛使用的编译器都实现了这个功能。

    如果除了保存N 整数列表之外,您对A 没有任何用处,则可以只使用类似于以下行的临时对象

    C = pack([(ix, ix = 1,N)],themask)
    

    其中ix 是先前声明的整数。这个表达式 -- [(ix, ix = 1,N)] -- 使用 implied-do 循环来填充临时向量。

    您现在可以循环遍历C 的值,如果这是您想做的,但也许您想使用C 作为另一个rank-1 数组的向量索引,例如D(C)

    这里没有摆弄循环,但我没有声称这种方法会比@francescalus 的基于循环的建议表现更好(或更差或不同)。

    【讨论】:

      【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-09
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多