回 帖 发 新 帖 刷新版面

主题:怎么穷举组合

请教各位,有多个变量例如s1, s2, s3. 它们的取值都是-1和1. 请问怎么穷举所有的组合, 这里的变量个数是不确定的, 由输入决定. 好像循环不好使了. 有熟悉算法的大侠麻烦给点建议. 谢谢了!!!

回复列表 (共5个回复)

沙发

如果是单变量,貌似不太可能。

如果是数组或者指针链表还有点可能。为什么循环不好使呢?

还有,我不太明白所谓的“穷举”组合是什么意思。是把所有组合都显示一次还是什么呢?

可否举例说明?

板凳


不是单变量,一个一维数组, 元素个数由输入决定. 每个元素只能取-1或1. 要是3个元素的话,这个数组有8种取值组合. 就是要穷举所有的取值组合.

3 楼

[quote]如果是单变量,貌似不太可能。

如果是数组或者指针链表还有点可能。为什么循环不好使呢?

还有,我不太明白所谓的“穷举”组合是什么意思。是把所有组合都显示一次还是什么呢?

可否举例说明?[/quote]
不是单变量,一个一维数组, 元素个数由输入决定. 每个元素只能取-1或1. 要是3个元素的话,这个数组有8种取值组合. 就是要穷举所有的取值组合.

4 楼

简单的代码:

[quote]Program Main
  Implicit None
  Integer :: i , iN
  Read( * , * ) iN
  Do i = 0 , 2**iN - 1
    write( * , '(B9.9)' ) i
  End Do
End Program Main[/quote]

复杂一些,具有通用性的代码:
(下面的代码可以改为每个元素具有4个,或者5个取值)
[quote]Program Main
  Implicit None
  Integer :: iN
  Integer , parameter    :: iNTable = 2
  Integer , parameter    :: iTable( iNTable ) = (/-1,1/)
  Integer , allocatable  :: iData(:)
  Read( * , * ) iN
  Allocate( iData( iN ) )
  iData(:) = iTable( 1 )
  call ShowData( iData , 1 )
Contains

  Recursive Subroutine ShowData( iData , iLoop )
    Integer , Intent( INOUT ) :: iData(:)
    Integer , Intent( IN)     :: iLoop
    Integer :: i
    if ( iLoop <= size( iData ) ) then      
      Do i = 1 , iNTable
        iData( iLoop ) = iTable(i)
        call ShowData( iData , iLoop+1 )
        if ( iLoop == size( iData ) ) write( * , * ) iData
      End Do      
    end if
  End Subroutine ShowData  
End Program Main[/quote]

5 楼

[quote]简单的代码:

[quote]Program Main
  Implicit None
  Integer :: i , iN
  Read( * , * ) iN
  Do i = 0 , 2**iN - 1
    write( * , '(B9.9)' ) i
  End Do
End Program Main[/quote]

复杂一些,具有通用性的代码:
(下面的代码可以改为每个元素具有4个,或者5个取值)
[quote]Program Main
  Implicit None
  Integer :: iN
  Integer , parameter    :: iNTable = 2
  Integer , parameter    :: iTable( iNTable ) = (/-1,1/)
  Integer , allocatable  :: iData(:)
  Read( * , * ) iN
  Allocate( iData( iN ) )
  iData(:) = iTable( 1 )
  call ShowData( iData , 1 )
Contains

  Recursive Subroutine ShowData( iData , iLoop )
    Integer , Intent( INOUT ) :: iData(:)
    Integer , Intent( IN)     :: iLoop
    Integer :: i
    if ( iLoop <= size( iData ) ) then      
      Do i = 1 , iNTable
        iData( iLoop ) = iTable(i)
        call ShowData( iData , iLoop+1 )
        if ( iLoop == size( iData ) ) write( * , * ) iData
      End Do      
    end if
  End Subroutine ShowData  
End Program Main[/quote][/quote]
非常棒的代码,原来子程序可以递归调用,学习了. 谢谢!!

我来回复

您尚未登录,请登录后再回复。点此登录或注册