如您所见,如何处理nn(作为输入参数)循环在以下子程序中?还是有一些更好的方法来解决以下问题?谢谢!
subroutine sub(nn,kk,cc,d,res)
implicit none
integer res0,res
integer nn,kk(nn),kk2(nn),d(nn),cc(nn)
res=0
do kk(1)=0,d(1)
do kk(2)=0,d(2)
do kk(3)=0,d(3)
...
do kK(nn)=0,d(nn)
res0=0
kk2=kk ! They are arrays.
call othersub(kk2,nn,res0)!So array kk should be obtained for this othersub().
res=res+res0
end do
...
end do
end subroutine
答案 0 :(得分:3)
为什么不能这样:
ntot=1
do i=1,nn
ntot=ntot*(d(i)+1)
enddo
do k=1,ntot
n=k
do i=1,nn
kk(i)=mod(n,d(i)+1)
n=n/(d(i)+1)
enddo
!... use the array kk as you want
enddo
答案 1 :(得分:1)
有两种可能的方法:递归和非递归。取决于你如何跟随递归。
module NestedMod
contains
! Dummy routine to do something
subroutine Something(loop, loopMax, res)
integer, dimension(:), intent(in):: loop
integer, intent(in):: loopMax
real, intent(inout):: res
res = res + sum(loop)
end subroutine Something
recursive subroutine descend(current, maxDepth, loop, maxLoop, DoSomething, res)
integer, intent(in):: current
integer, intent(in):: maxDepth
integer, dimension(:), intent(inout):: loop
integer, dimension(:), intent(in):: maxLoop
real, intent(out):: res
interface
subroutine DoSomething(a, asize, res)
integer, dimension(:), intent(in):: a
integer, intent(in):: asize
real, intent(inout):: res
end subroutine DoSomething
end interface
! More efficient timewise to do it separately
if (current .eq. maxDepth) then
do ii = 0, maxLoop(current)
loop(current) = ii
call DoSomething(loop, maxDepth, res)
end do
else
do ii = 0, maxLoop(current)
loop(current) = ii
call descend(current + 1, maxDepth, loop, maxLoop, DoSomething, res)
end do
end if
end subroutine descend
subroutine ascend(maxDepth, maxLoop, DoSomething, res)
integer, intent(in):: maxDepth
integer, dimension(:), intent(in):: maxLoop
real, intent(out):: res
interface
subroutine DoSomething(a, asize, res)
integer, dimension(:), intent(in):: a
integer, intent(in):: asize
real, intent(inout):: res
end subroutine DoSomething
end interface
integer, allocatable:: loop(:)
integer:: depth
allocate(loop(maxDepth))
loop = -1
depth = 1
do while (depth .gt. 0)
loop(depth) = loop(depth) + 1
if (loop(depth) .gt. maxLoop(depth)) then
! reset loop counter
loop(depth) = -1
! ascend
depth = depth - 1
! off the top?
if (depth .eq. 0) exit
else if (depth .lt. maxDepth) then
! descend
depth = depth + 1
else
call DoSomething(loop, maxDepth, res)
end if
end do
deallocate(loop)
end subroutine ascend
end module NestedMod
program main
use NestedMod
integer, parameter:: DEPTH = 5
integer, dimension(DEPTH):: loop, loopMax
integer:: size, index
real:: res
loopmax = (/2, 3, 5, 2, 3 /)
res = 0
call descend(1, DEPTH, loop, loopMax, Something, res)
print *, 'Recursive res = ', res
res = 0
call ascend(DEPTH, loopMax, Something, res)
print *, 'Non recursive res = ', res
end program