如何退出嵌套的Fortran循环?

如何退出嵌套的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

我正在尝试编写一个程序(用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)

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