So beenden von verschachtelten Fortran-Schleifen?

Ich versuche, ein Programm zu schreiben (in Fortran 95), der Sie findet, minimal ZERLEGUNG der natürlichen zahlen bis N in eine Summe von höchstens 4 positive ganze zahlen sind.

Ich habe versucht, hinzufügen und entfernen von Anweisungen für eine Weile, um es zu stoppen nur minimale Zersetzung, aber ich bin nicht immer überall. Wie kann ich das Programm stoppen, sobald diese gefunden, wird die minimale Zersetzung?

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
  • Willkommen, nehmen Sie unbedingt den tour. . Du fragst, wie ein Fortran-Programm? STOP wird verwendet für die stackoverflow.com/questions/30462371/… stackoverflow.com/questions/31873986/… Oder Fragen Sie, wie zu erkennen, das minimum?
  • STOP Stoppt alles. Ich möchte wissen, wie kann ich das Programm nur geben Sie mir die minimalen Zersetzung, so dass ein Quadrat nur mir selbst, statt andere mögliche Summen von Quadraten. Ab 4 dass Sie mir nur 2 0 0 0 und auch nicht 1 1 1 1.
  • Naja man kann immer exit die Schleife anstelle der stop, dass ist nicht das Problem. So sind Sie in der Lage, Sie zu erkennen, müssen die minimale?
  • Ich habe versucht, verlassen nach `d*d….eq. x‘ ist, aber es gibt es. Auch in jeder anderen Schleife.
  • haben Sie irgendwelche Ideen?
  • Gut, ich verstehe nicht, was Ihr bittet. Fragen, wie man erkennt ein minimum? Oder wie Sie eine Schleife beenden? Ich verstehe deine Frage nicht. Auch, was das ist „gibt es“?
  • Wie würde ich das umsetzen, eine Pause nach dem minimum?
  • Damit Sie wissen, wenn Sie sind in der minimalen?
  • Es hängt von der aktuellen integer, wenn ich nur d, dann Pause, sonst find c etc.
  • Ich weiß immer noch nicht versteht, Ihr. Will nur sagen, dass exit label verlassen einer Loop-Schleife mit label label ausreichen, um Sie? Die Schleife mit dem label kann der äußerste eine oder andere. Oder brauchen Sie eine Hilfe mit den ifs?
  • Ich werde versuchen, mit Aufklebern; ich danke Ihnen.

InformationsquelleAutor | 2017-10-08



2 Replies
  1. 3

    Als ich erklärte, in den Kommentaren, ich bin mir nicht sicher, Sie Fragen sich nur, wie man ausbrechen des loops, oder für mehr.

    Können Sie direkt aus jeder Schleife über die EXIT – Anweisung. Zum beenden einer Schleife, die nicht in der innersten Schleife sind Sie derzeit verwenden Sie eine Schleife markiert und mit dem label-in der EXIT – Anweisung zu beenden, dass die Besondere Schleife.

    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
    
    • Ich beschriftete die erste Schleife nach dem äußeren ein und verlassen es, funktioniert Super danke.
    • BTW, wir normalerweise setzen Sie nicht den ,1 Schritt in jede Schleife und wir stark bevorzugen == und /= über .eq. und .neq. für die Lesbarkeit.
    • Ich würde schätzen, eine sauberere version. Dieser ist auch extrem langsam.
    • Das ist, warum ich wurde gefragt, viele Male, und ich war zu betonen, ich bin nicht sicher, was Sie sind bis zu! Wenn Sie akzeptiert die Antwort, die ich davon ausgegangen, dass Sie sattisfied und bearbeitet die Frage entsprechend. Also bitte genau beschreiben, wie Sie bei der Bestimmung der Mindest-und wenn Sie dabei Hilfe benötigen.
    • Ich sage gerade, es zu beenden, sobald es eine Lösung gefunden, es wird mit der kleinsten d und dann kleinste cetc.
    • Ist es möglich, die schreib-Funktion nur die nicht-null-zahlen?
    • Ein paar Anmerkungen: Wenn Sie ein do-Konstrukt mit einer do-Konstrukt-Namen, die Ende-zu tun hat, um anzugeben, dass Namen. Auch das erste positive Ergebnis ist minimal, so dass keine, WENN erforderlich. Aber ich denke, Sie wollen Zyklus äußeren zu verarbeiten, die nächsten x. Der O. P. wollte der write-Anweisung zu drucken nur nicht-null-zahlen, so würde ich ändern, der Inhalt des Blocks, WENN (Sorry, ich weiß nicht, wie dieses format) $$\begin{align}&\text{ write(*,'(i0,“ = „,i0″**2″:3(“ + „,i0,“**2“:))‘) x, &}\\ &\text{ reshape([d,c,b,a],[count([d,c,b,a]/=0)])}\\ &\text{ Zyklus äußere}\end{align}$$
    • Ich kann nicht entziffern diese. Mit dem ersten Punkt hast du Recht, der name fehlt auf der end do. Ich habe nicht wirklich Graben innerhalb des O. P. des code, denn es war nicht klar, was er will (ich fragte mehrere Male, wie ist die minimale anerkannt! Keine wirkliche Antwort…). Ich will nicht verfolgen, dass jetzt. Sie sind frei, um alles zu erklären in Ihrer Antwort.
    • Ja, es scheint, Sie darf nur eine Zeile code also mein Vorschlag wäre, ersetzen Sie den Inhalt des Blocks, WENN mit write(*,'(i0," = ",i0"**2":3(" + ",i0,"**2":))') x,reshape([d,c,b,a],[count([d,c,b,a]/=0)]);cycle outer und das sollte genügen die O. P. ‚ s-Anforderungen.

  2. 0

    Alten thread, aber es ist irgendwie ein lustiges problem, also ich dachte, ich würde post meine eigene interpretation.

    Zuerst aus, wenn wir ein wenig schummeln und Blick auf die Lösung es kann gesehen werden, dass alle 4 Quadrate sind nur erforderlich, wenn x=4**k*(8*m+7). So suchen wir uns Billig für 1-oder 2-Platz-Lösungen und auf Fehler zu entscheiden, die von den oben genannten Kriterium, ob Sie suchen für eine 3 – oder 4-square-Lösung.

    Dann, wenn wir die Struktur unserer loops, count-down aus dem größten eine solche, die a**2 <= x, dann ist die größte b <= a, so dass a**2+b**2 <= x und so weiter. Dieser nimmt das problem von O(x**4) nach O(x**1.5), so kann es viel schneller gehen.

    Für die Ausgabe-format, durch den klugen Einsatz der colon-format, wir können schreiben, ein single-format druckt die Ergebnisse in vielleicht einem besser lesbaren Weise.

    ! 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
    

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.