![]() |
AW: Erstellung einer Schleife mit drei Überprüfungen
Zitat:
Du fragt wegen allen anderen Primzahlen. Hier Code.
Delphi-Quellcode:
Lade den Code in der IDE und steppe durch wie TurboMagic geschrieben hat.
var teiler, pruefebis, zahl : integer;
ist_prim : boolean; .... zahl := 91; ist_prim := true; teiler := 3; pruefebis := trunc(sqrt(zahl)); while ist_prim and ( teiler <= pruefebis ) do begin ist_prim := zahl mod teiler <> 0; inc( teiler, 2 ); // teiler := teiler + 2; end; Zum Code: Wir nehmen zuerst ist_prim:= TRUE an und werden vielleicht später (in der while Schleife) das Gegenteil beweisen. zahl ist im Beispiel 91. Du weisst, dass es einen echten Teiler von 91 <= sqrt(91) geben muss, wenn 91 nicht prim ist. Wir prüfen also für teiler mit den Werten 3,5,...9, ob zahl durch teiler teilbar ist. Wenn dem so ist, wird ist_prim in der while Schleife FALSE. => Die Schleife wird wegen der Abbruchbedingung (while ist_prim and ( teiler <= pruefebis ) do) verlassen. Am Ende der while Schleife ist ist_prim TRUE, wenn zahl eine Primzahl ist, sonst FALSE Da ihr wahrscheinlich keine "function" benutzen dürft, ist die Aufgabe mit den Primzahlzwillingen etwas aufwändig [und ohne die Verwendung von "function" vielleicht auch ein wenig nutzlos ;-)]. |
AW: Erstellung einer Schleife mit drei Überprüfungen
F7 ist, Dank der bescheuert standardrdmäßig aktiven Option "Debug-DCUs", seit zuvielen Jahren nicht mehr so toll.
also F8 oder in den Projektoptionen die Debug-DCUs deaktivieren, es sei denn jemandem macht es Spaß, wenn er die VCL/RTL/System-Units ebenfalls debuggen will. |
AW: Erstellung einer Schleife mit drei Überprüfungen
@Michael II ist es möglich das ganze auch in einer repeat schleife zu verpacken?
Wie mach man das jetzt mit dem Primzahlzwilling, da istprime ja boolean ist klappt es in der nächsten überprüfung nichtmehr mit zahl+2 = istprime |
AW: Erstellung einer Schleife mit drei Überprüfungen
Dieser Code gibt dir aus, ob eine Zahl gerade ist, ob fibo, ob prim, ob zwillingsprim.
Da du sicher keine function istprim(zahl) verwenden darfst, merken wir uns halt in zwei booleschen Variablen, ob die letzte ungerade Zahl (zahl-2) prim war (letzte_warprim) und ob die nächste ungerade (zahl+2) es sein wird (naechste_istprim). So müssen wir jede zahl nur einmal auf prim prüfen. Die "Spezialwerte" 0,1,2 geben wir direkt aus. (Man müsste den Code durch diese drei "Sonderfälle" aufblähen. - Tun wir nicht.) Was macht das Programm? Fibo: Für fibo berechnen wir am Anfang die kleinste Fibo-Zahl f, welche >= LOWER_BORDER ist. Dann geht's ab in die while Schleife. Sobald zahl=f wissen wir "fibo!". Wir setzen im fibo Fall istfibo:=TRUE und müssen das nächste Glied f der Fibofolge berechnen. Bei der Berechnung von f=f[n] greifen wir auf die gespeicherten Werte von f[n-1] und f[n-2] zurück. Gerade: istgerade := zahl mod 2 = 0; und das war's bereits. Primzahlen und deren Zwillinge: Für Zahlen, welche ungerade sind, prüfen wir auf prim. Wir prüfen dabei nicht die aktuelle Zahl, sondern "zahl+2". Grund: Wir müssen für die Bewertung "zahl ist Zwilling oder nicht" wissen, ob die nächste ungerade Zahl "zahl+2" prim ist. Wir speichern in naechste_istprim ab, ob "zahl+2" prim ist. In letzte_warprim merken wir uns, ob die letzte ungerade Zahl prim war. In diese_istprim steht, ob zahl prim ist. diese_istprim berechnen wir dabei nicht via Faktorzerlegung von zahl: Wir wissen ja dank letzte_warprim, ob zahl prim ist oder nicht. "zahl" ist Teil eines Primzahlzwillings, wenn primzwilling := diese_istprim and ( letzte_warprim or naechste_istprim ); Fertig - Viel Spass beim Denken.
Delphi-Quellcode:
var teiler, sqrt_n, naechste, zahl, fn_1, fn_2, f : int64;
primzwilling, istfibo, istgerade, letzte_warprim, naechste_istprim, diese_istprim : boolean; const LOWER_BORDER = 0; UPPER_BORDER = 50; begin if ( LOWER_BORDER = 0 ) then writeln( '0 even: TRUE fib: TRUE prim: FALSE twinprim: FALSE' ); if ( LOWER_BORDER <= 1 ) and ( 1 <= UPPER_BORDER ) then writeln( '1 even: FALSE fib: TRUE prim: FALSE twinprim: FALSE' ); if ( LOWER_BORDER <= 2 ) and ( 2 <= UPPER_BORDER ) then writeln( '2 even: TRUE fib: TRUE prim: FALSE twinprim: FALSE' ); if ( LOWER_BORDER mod 2 = 0 ) then zahl := LOWER_BORDER-3 else zahl := LOWER_BORDER-4; if ( zahl < 3 ) then begin zahl := 3; naechste_istprim := true; // 3 ist Primzahl end; fn_1 := 1; fn_2 := 1; f := 2; while ( f < zahl ) do // berechne die kleinste Fibo-Zahl f, welche >= LOWER_BORDER begin f := fn_1 + fn_2; fn_2 := fn_1; fn_1 := f; end; while ( zahl <= UPPER_BORDER ) do begin istfibo := f = zahl; if istfibo then begin // die nächste Fibozahl wird berechnet f := fn_1 + fn_2; fn_2 := fn_1; fn_1 := f; end; istgerade := zahl mod 2 = 0; if not istgerade then begin diese_istprim := naechste_istprim; // in durchlauf "zahl-2" haben wir berechnet, ob "zahl" prim ist naechste := zahl + 2; // die nächste ungerade zahl nach "zahl" auf prim prüfen sqrt_n := trunc(sqrt(naechste)); // bis zu diesem wert suchen wir nach möglichen teilern von naechste teiler := 3; naechste_istprim := true; // wir nehmen mal an, "naechste" sei prim while naechste_istprim and ( teiler <= sqrt_n ) do begin // und prüfen, ob dem so ist naechste_istprim := naechste mod teiler <> 0; inc( teiler, 2 ); end; // naechste_istprim = true, wenn naechste=zahl+2 prim ist // wir prüfen, ob "zahl" zu einem Zwilling gehört primzwilling := diese_istprim and ( letzte_warprim or naechste_istprim ); letzte_warprim := diese_istprim; // wir merken uns für runde "zahl+2", ob "zahl" prim ist end else begin diese_istprim := false; // "zahl" ist gerade also nicht prim primzwilling := false; // ..und damit auch nicht Teil eines Zwillings end; if ( zahl >= LOWER_BORDER ) then // Ausgabe writeln(zahl, ' even: ', istgerade, ' fib: ', istfibo, ' prim: ', diese_istprim, ' twinprim: ', primzwilling ); inc( zahl ); end; readln; |
AW: Erstellung einer Schleife mit drei Überprüfungen
Das sieht sehr gut aus, ich habe in der zwischenzeit auch meinen code bearbeitet, jedoch wird auf einmal nur bis 1 ausgegeben.
Bevor ich die zwei neuen repeat schleifen eingefügt hab hat es bis 50 geklappt, siehst du vielleicht woran es liegt.
Delphi-Quellcode:
program ueb04;
{$APPTYPE CONSOLE} {$R+,Q+,X-} uses System.SysUtils; const LOWER_BORDER = 0; UPPER_BORDER = 50; var even: boolean; fib: boolean; twinprim: boolean; NextPrim: boolean; PrevPrim: boolean; zahl: integer; Primzahl: boolean; teiler: integer; uebrig: integer; a: integer; b: integer; c: integer; begin for zahl := LOWER_BORDER to UPPER_BORDER do begin even := false; fib := false; twinprim := false; if zahl > 1 then begin // Überprüfung ob gerade: even := (zahl mod 2 = 0); // Überprüfung ob Primzahl: teiler := 1; repeat teiler := teiler + 1; uebrig := zahl mod teiler; until (uebrig = 0); Primzahl := (zahl = teiler); end; if Primzahl then begin Teiler:= 1; repeat teiler := teiler + 1; uebrig := zahl + 2 mod teiler; until (uebrig = 0); NextPrim := (zahl + 2) = teiler; end; if Primzahl and (zahl > 3) then begin Teiler:= 1; repeat teiler := teiler + 1; uebrig := zahl - 2 mod teiler; until (uebrig = 0); PrevPrim := (zahl - 2) = teiler; end; twinprim := Primzahl and (NextPrim or PrevPrim); // Überprüfung ob Teil der Fibonacci-Folge: a := 0; b := 1; c := 0; while (a < zahl) and not fib do begin c := a + b; a := b; b := c; fib := c = zahl; end; WriteLn(zahl, ' even: ', even, ' fib: ', fib, ' twinprim: ', twinprim); end; readln; end. |
AW: Erstellung einer Schleife mit drei Überprüfungen
uebrig := zahl - 2 mod teiler; ist nicht das, was du willst.
mod wird vor +*-/ ausgewertet. Was du willst ist uebrig := ( zahl - 2 ) mod teiler; In deinem Code berechnest du in jeder Runde drei Mal, ob eine Zahl (du rechnest für zahl-2, zahl und zahl+2) prim ist. Wie du gesehen hast geht es auch mit einer Berechnung pro Runde: Du könntest dir jeweils prim oder nicht für zahl und zahl+2 merken. In der nächsten "ungeraden zahl Runde" kannst du dann auf diese Werte zurückgreifen und musst nur für "zahl+2" rechnen. Wie besprochen: Ausser 2 ist keine Primzahl gerade. Überprüfe also nur ungerade teiler. teiler := teiler + 2; Wie besprochen: Prüfe nur für ungerade Teiler von 3 bis sqrt(zahl).
Delphi-Quellcode:
Fibo müsstest du nicht für jede Zahl immer neu berechnen. Es reicht, wenn du dir immer die nächste Fibo-Zahl f > zahl merkst und dann in jeder Runde auf f=zahl prüfst.
ist_prim := true;
teiler := 3; pruefebis := trunc(sqrt(zahl)); repeat ist_prim := zahl mod teiler <> 0; inc( teiler, 2 ); until not ist_prim or ( teiler > pruefebis ); Das spielt hier keine grosse Rolle - aber Effizienz in Schleifen ist wichtig ;-). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz