如何退出嵌套的Fortran循环?
我正在尝试编写一个程序(用Fortran 95编写),该程序将N以下的自然数分解为最多4个正整数之和 一段时间以来,我一直在尝试添加和删除语句,以使其仅在最小分解时停止,但我没有取得任何进展。如何使程序在找到最小分解后立即停止如何退出嵌套的Fortran循环?,fortran,Fortran,我正在尝试编写一个程序(用Fortran 95编写),该程序将N以下的自然数分解为最多4个正整数之和 一段时间以来,我一直在尝试添加和删除语句,以使其仅在最小分解时停止,但我没有取得任何进展。如何使程序在找到最小分解后立即停止 PROGRAM SummeQuadrat IMPLICIT NONE real:: start,finish integer:: a,b,c,d,g,x,y write(*,*) "Max n" read (*,*) y call cpu_time(start
PROGRAM SummeQuadrat
IMPLICIT NONE
real:: start,finish
integer:: a,b,c,d,g,x,y
write(*,*) "Max n"
read (*,*) y
call cpu_time(start)
do x=1,y,1
do a=0,x,1
do b=a,x-a,1
do c=b,x-b,1
do d=c,x-c,1
if (a**2+b**2+c**2+d**2 .eq. x) then
write(*,*) "x=",x,d,c,b,a
end if
end do
end do
end do
end do
end do
call cpu_time(finish)
write(*,*)finish-start
end program SummeQuadrat
正如我在评论中所解释的,我不确定你只是在问如何打破循环或者更多 您可以使用
EXIT
语句跳出任何循环。要退出当前不是最内层循环的循环,请使用带标签的循环,并使用exit
语句中的标签退出该特定循环
outer: do x = 1, y
do a = 0, x
do b = a, x-a
do c = b, x-b
do d = c, x-c
if (a**2+b**2+c**2+d**2 == x) then
write(*,*) "x=",x,d,c,b,a
if (minimal(a,b,c,d)) exit outer
end if
end do
end do
end do
end do
end do outer
旧线程,但这是一个有趣的问题,所以我想我可以发布自己的解释 首先,如果我们稍微作弊一下,看一眼就会发现,只有当x=4**k*(8*m+7)时,才需要所有4个正方形。因此,我们可以廉价地搜索1或2平方解,并且在失败时根据上述标准决定是否搜索3或4平方解
然后,当我们构造循环时,从最大的a开始倒数,这样一个**2欢迎,一定要采取。你是在问如何停止Fortran程序吗<代码>停止用于此,或者您正在询问如何识别最小值?停止停止一切。我想知道如何让程序只给我最小的分解,所以一个平方只给我自己,而不是其他可能的平方和。Ex 4只给我2 0 0 0,而不是1 1。你总是可以退出循环,而不是停止,这不是问题所在。你能认出你有最小值吗?我试着在'd*d.eq.之后退出。但它把事情搞砸了。也在其他循环中。你有什么想法吗?我在外部循环之后标记第一个循环并退出,非常感谢。顺便说一句,我们通常不放置
,1
进入每个循环,我们强烈希望=
和/=
优于.eq.
和.neq.
的可读性。我希望有一个更干净的版本。这一个也非常慢。这就是为什么我问了很多次,我强调我不知道你在做什么!当你接受答案时,我认为你已经满足了,并相应地编辑了这个问题。因此,请准确描述您是如何确定最小值的,以及您是否需要帮助。我只是告诉它一旦找到解决方案就退出,它将使用最小的d
,然后使用最小的c
等。
! squares.f90 -- Prints out minimal decomposition x into squares
! for 1 <= x <= y (user input)
program squares
use ISO_FORTRAN_ENV, only: REAL64
implicit none
! Need this constant so we can take the square root of an
! integer.
real(REAL64), parameter :: half = 0.5_REAL64
real start, finish
integer a,b,c
integer amax,bmax,cmax,dmax
integer amin,bmin,cmin
integer x,y
! Format for printing out decomposition into squares
character(40) :: fmt = '(i0," = ",i0"**2":3(" + ",i0,"**2":))'
integer nzero
! Get uper bound from user
write(*,'(a)',advance='no') 'Please enter the max N:> '
read(*,*) y
call cpu_time(start)
! Loop over requested range
outer: do x = 1, y
amax = sqrt(x+half)
! Check for perfect square
if(amax**2 == x) then
write(*,fmt) x,amax
cycle outer
end if
! Check for sum of 2 squares
amin = sqrt(x/2+half)
try2: do a = amax, amin, -1
bmax = sqrt(x-a**2+half)
if(bmax > a) exit try2
if(a**2+bmax**2 == x) then
write(*,fmt) x,a,bmax
cycle outer
end if
end do try2
! If trailz(x) is even, then x = 4**k*z, where z is odd
! If further z = 8*m+7, then 4 squares are required, otherwise
! only 3 should suffice.
nzero = trailz(x)
if(iand(nzero,1)==0 .AND. ibits(x,nzero,3)==7) then
amin = sqrt(x/4+half)
do a = amax, amin, -1
bmax = sqrt(x-a**2+half)
bmin = sqrt((x-a**2)/3+half)
do b = min(bmax,a), bmin, -1
cmax = sqrt(x-a**2-b**2+half)
cmin = sqrt((x-a**2-b**2)/2+half)
do c = min(cmax,b), cmin, -1
dmax = sqrt(x-a**2-b**2-c**2+half)
if(a**2+b**2+c**2+dmax**2 == x) then
write(*,fmt) x,a,b,c,dmax
cycle outer
end if
end do
end do
end do
else
amin = sqrt(x/3+half)
do a = amax, amin, -1
bmax = sqrt(x-a**2+half)
bmin = sqrt((x-a**2)/2+half)
do b = min(bmax,a), bmin, -1
cmax = sqrt(x-a**2-b**2+half)
if(a**2+b**2+cmax**2 == x) then
write(*,fmt) x,a,b,cmax
cycle outer
end if
end do
end do
end if
! We should have a solution by now. If not, print out
! an error message and abort.
write(*,'(*(g0))') 'Failure at x = ',x
stop
end do outer
call cpu_time(finish)
write(*,'(*(g0))') 'CPU time = ',finish-start
end program squares