【问题标题】:How to obtain all variations of an array with elements being zero or one如何获得元素为零或一的数组的所有变体
【发布时间】:2016-03-27 04:21:08
【问题描述】:

我将针对数组元素的可能值编写一个 do 循环。更具体地说,我有一个数组,比如说A(:),大小为n,数组A 的任何元素都可以是01。我想遍历A 元素的所有可能值。当然简单的方法是

do A(1)=0, 1
 do A(2)=0, 1
  ....
   ! do something with array A

 end do 
end do 

但是我的数组很大,这个方法不是很适合。有没有更好的方法来做到这一点?

【问题讨论】:

  • 我不确定我是否得到了这个问题...您是否想要数组的所有可能变体,其中元素为 0 或 1?例如:00011011 对于长度为 2 的数组?
  • 亲爱的亚历山大,是的,没错。我想拥有数组的所有可能变化,其中元素为零或一。但是为了节省内存,我不想将所有可能的配置保存在更大的矩阵中。
  • 数组会有多大?
  • 2^30 配置。实际上 A(:) 的大小是 30,因此总配置是 2^30。
  • 还请注意,不能在循环内更改循环索引!此外,您不能将数组的元素用作循环计数器。

标签: arrays fortran do-loops


【解决方案1】:

既然这只是二进制,为什么不(错误)使用整数来完成这项任务?只需将每个组合的整数加一,然后使用btest 读出相应的位:

program test
  implicit none
  integer, parameter  :: n = 3
  integer             :: i
  integer             :: A(n)
  integer             :: idx(n) = [(i, i=0,n-1)] ! bit positions start at zero

  ! Use a loop to increment the integer
  do i=0,2**n-1
    ! Get the bits at the lowest positions and map true to "1" and false to "0"
    A = merge( 1, 0, btest( i, idx ) )
    print *,A
  enddo
end program

这个简单的代码用所有组合(一次一个)填充A,并连续打印它们。

./a.out 
           0           0           0
           1           0           0
           0           1           0
           1           1           0
           0           0           1
           1           0           1
           0           1           1
           1           1           1

注意,Fortran 只有signed integers,所以最高位在这里不可用。如果您从零开始,则最多可以使用2^(32-1) 组合(默认)4 字节整数,如此处所示(数组长度最多为 31)。

要获得完整范围,请按以下方式执行循环:

  do i=-huge(1)-1,huge(1)

这为您提供了长度为 32 的数组的完整 2^32 不同变体。

【讨论】:

  • 感谢您提供有趣的解决方案。将来我必须将我的代码概括为非二进制值。如果 A(i) 的值为 0,1,...,M.,是否有类似的技巧?
  • @Math-fort 是的,但是这个通用解决方案已经得到回答,例如,here :)
  • 亲爱的 Alexander,有没有办法处理长度为 2^(32) 的数组?谢谢,:-(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-13
  • 2018-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多