For-do Schleife mit Sprung
Ich programmiere gerade einen Primzahlgenerator. Der soll von einer Zahl, bis zu einer Zahl(die der Anwender eingibt) prüfen.
Da braucht man ja eigentlich nur alle ungeraden Zahlen zu prüfen, denn alle geraden Zahlen kann man ja durch 2 teilen. Ich habe die Suchfunktion schon fertig programmiert, allerdings mit einer For-Do-Anweisung. Und die geht bei mir immer nur 1 hoch. Kann man da noch irgendwas dranhängen, wie z.B.:
Delphi-Quellcode:
Sollte es keine For-DoAnweisung mit einem solchen(oder ähnlichem) Feature geben, was könntet ihr mit noch empfehlen.
for I := 3 to ZAHL Step 2 do begin
... end; Es kommt halt auch auf die Geschwindigkeit an, sonst würde ich alle Zahlen nehmen, und vorher mit "if Trunc(Zahl/2)*2 = Zahl then GERADE ZAHL" auf gerade Zahlen überprüfen lassen, aber da dauerte es (wenn auch nur wenige Sekunden, aber das summiert sich ja) länger. Danke schonmal! :mrgreen: |
Re: For-do Schleife mit Sprung
Ein Hallöle von http://www.FrankNStein.de/Smiley-Wolke.gif,
Code:
Da ja auch nur bis Zahl / 2 geprüft werden braucht:
[b]For[/b] I := 1 [b]to[/b] (ZAHL - 1) [b]div[/b] 2 [b]do Begin[/b]
[color=red]TestZahl[/color] := (I * 2) + 1; ... [b]End[/b];
Code:
http://www.delphipraxis.net/images/common/divider.jpg
[b]For[/b] I := 1 [b]to[/b] ZAHL [b]div[/b] 4 [b]do Begin[/b]
[color=red]TestZahl[/color] := (I * 2) + 1; ... [b]End[/b]; http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif |
Re: For-do Schleife mit Sprung
du könntest in die prozedur doch "inc(I)" einfügen
|
Re: For-do Schleife mit Sprung
Meines wissens nach darf man die Schleifenvariable nicht innerhalb der Schleife verändern :mrgreen:
|
Re: For-do Schleife mit Sprung
und wieso?
|
Re: For-do Schleife mit Sprung
Stell dir vor was passiert wenn du i größer als die Bedingung zum Abbruch der Schleife änderst ;)
Außerdem meckert der Komplizierer dann :P |
Re: For-do Schleife mit Sprung
Entweder du nimmst ne while oder eine repeat Schleife, das die einzige möglichkeit in meinen augen :cyclops:
|
Re: For-do Schleife mit Sprung
Ist das nicht egal, welche Schleife?
Alle 3 bewirken, meiner Meinung nach, das gleiche:
Delphi-Quellcode:
Naja, gleich ist es nicht, aber es müsste ja das Ähnliche bewirken, oder?
for i:=1 to Zahl do
begin ... end; while i<Zahl do begin ... end; repeat ... until i=Zahl |
Re: For-do Schleife mit Sprung
Es ging ja darum, dass die Laufvariable geändert werden soll. Das ist bei For-Schleifen nun mal nicht möglich. Naja Repeat und While ist eigentlich das gleiche - eins hat halt ne Eintrittsbedingung und das andre ne Austrittsbedingung. Musste halt immer nehmen wie's am besten passt grad (auch von der Logik her). Der Quellcode sollte ja möglichst selbstkommentierend sein.
MfG Niels |
Re: For-do Schleife mit Sprung
Bei while und repeat bist du selbst dafür verantwortlich dass die Abbruchbedingung greift, sprich hie rmuss man in diesem Fall selber i inkrementieren, bei der for-Schleife wird vorher die Anzahl der Schleifendurchläufe ermittelt und dann die Schleife auch nur so und so viel mal druchlaufen.
Das man den Schleifen in einer for-Schleife nicht ändern kann (so ohne weiteres, mit einem Trick geht es) ist Compiler bedingt. Mit C/C++ Compiler kann man das machen. Nur wenn der Compiler weiß, wie oft eine Schleife durchlaufen wird, kann er besser optimieren. Desweitern sehe ich keinen Sinn darin in einer for-Schleife den Schleifenzähler ändern zu wollen, sie wurde extra für Schleifen komzepiert bei denen man weiß, wie oft sie durchlaufen wird. Die Lösung wäre also hier eine while-Schleife. |
Re: For-do Schleife mit Sprung
Zitat:
|
Re: For-do Schleife mit Sprung
Genau Luckie zauber mal was aus deinem Hut (oder der roten Mütze :xmas: ) :)
|
Re: For-do Schleife mit Sprung
Abrakadabra, dreimal schwarzer Kater. Schwupps:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer; begin for i := 0 to 9 do begin Inc(Integer(Pointer(@i)^)); ShowMessage(IntToStr(i)); end; end; |
Re: For-do Schleife mit Sprung
goil! das ist ja end-praktisch. man sollte die while schleifen weglassen, die sind ja voll überflüssig :warn:
|
Re: For-do Schleife mit Sprung
Also überschreibst du nur die Stelle im Speicher (wo der Zählwert steht), ohne das der Compiler es beim kompilieren merkt??
|
Re: For-do Schleife mit Sprung
Ja. jedem Menschen fällt auf, dass
Delphi-Quellcode:
wenn man gleich viele @ wie ^s hat, wieder genau i ist. Aber der Compiler prüft sowas (zurecht) nicht nach. Allerdings habe ich immer gedacht, dass Schleifen intern anders funktionieren, und Luckies Gebastel daher eh nicht funktioniert. Aber eigentlich ist es mir ***egal, obs geht oder nicht, weil ich das (hoffentlich) nie brauchen werde!
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@i^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
Re: For-do Schleife mit Sprung
Vielen dank für diesen wertvollen Post, ich werd ihn mir einrahmen :D :thumb:
|
Re: For-do Schleife mit Sprung
ich helfe, wo ich kann! PS: Nicht überreiben, irgendwann meckert Delphi von wegen "zu lange Zeile"
|
Re: For-do Schleife mit Sprung
Was man eventuell dann beachten sollte, dass die schleife
Delphi-Quellcode:
die Abbruchsbedingung (wenn man das so nennen kann) bei i = n+1 liegt. Wenn i also erstmal > i+1 ist dann hat man ne feine Endlosschleife.
for i := m to n do
MfG Niels |
Re: For-do Schleife mit Sprung
Zitat:
der compiler übersetzt das dann entweder mit einen increase and jump oder einen decrease and jump und bricht ab wenn er den wert erreicht hat bzw wenn er 0 erreicht hat ... verändert man die variable, dann könnte da ziemlich schnell eine endlos schleife daraus werden ... |
Re: For-do Schleife mit Sprung
Zitat:
|
Re: For-do Schleife mit Sprung
Beide Schleifen sind wichtig, vllt solltet ihr euch mal klar machen was der Unterschied zwischen einer "Kopf" und ner "Fuß" gesteuerten Schleife ist ;)
|
Re: For-do Schleife mit Sprung
[offtopic] das Gegenteil von "Kopf" gesteuert ist "Schwanz" gesteuert [/offtopic]
Mein Beitrag mit "goil! dann..." war ironisch gemeint. Das nur nochmal für alle, denen das nicht ganz klar war. Fakt ist, dass man ausgehen von einer while-Schleife die beiden anderen relativ schnell geschrieben hat: bei der repeat-Schleife:
Delphi-Quellcode:
bei der for schleife:
anweisung;
while ISTrue do anweisung;
Delphi-Quellcode:
aber wer will das schon immer machen. Also doch gut, dass es alle drei gibt!
while soOft >= 0 do
begin dec(soOft); anweisung; end; |
Re: For-do Schleife mit Sprung
Zitat:
|
Re: For-do Schleife mit Sprung
Ich denke, ich werde mich für den Code von himitsu entscheiden, der ist für mich(auf Grund meiner Erfahrung und Faulheit) der Beste.
Danke für die vielen Antworten!. :thuimb: |
Re: For-do Schleife mit Sprung
noch ein tipp: du musst nichtmal bis "maxZahl div 2" durchgehen. "ceil(sqrt(maxZahl))" reicht!
|
Re: For-do Schleife mit Sprung
Die Anweisung kann ja schnell mal 10 Sekunden (und meistens noch drüber) dauern. Damit ich Fortschritte sehen kann, habe ich mir was ausgedacht:
Ich nehme mir die Startzeit und die Endzeit und führe dann SecondsBetween(...) aus. Allerdings ist eine Sekunde bei solchen größenverhältnissen nicht gerade genau. Aber mit einem Timer(der dann aller 10 ms den Zeitwert erhöht) kann ich's nicht machen, weil der ja seine Anweisungen erst nach der Beendigung der Primzahlsuche fortsetzt. Habt ihr noch 'ne Idee? |
Re: For-do Schleife mit Sprung
wie wird der Fortschritt angezeiht? Ruf in der Schleife mal die Refresh-Methode der entsprechenden Komponent auf. Oder pack das in einen Thread und lass dir vom Thread eine Message an dein fenster schicken bei jedem Fortschritt.
|
Re: For-do Schleife mit Sprung
Also der Fortschritt wird über eine TProgressBar angezeigt. Das habe ich schon ziemlich optimiert. Aber darüber sehe ich ja nicht, wie lange es von Zahl X bis Zahl Y gesucht hat. Ich habe ja schon oben meine momentane Zeitmessmethode beschrieben. Aber wie kann ich es Zehntelsekundengenau machen?
Wie meinst du das, mit der Refresh-Methode? Soll ich einen Timer mit der Aufgabe "Benötigte Zeit := Benötigte Zeit + 0,01" und den dann mit der Refresh-Methode aufrufen? |
Re: For-do Schleife mit Sprung
Luckie meinte, dass wenn du innerhalb deiner Methode den Progress erhöhst, man das trotzdem erst sehen wird, wenn deine Methode fertig abgearbeitet ist. Um das zu verhindern, und zwischendurch die ANzeige auf den aktuellen Stand, sollte man irgendwas von wegen Repaint/Refresh/Update einbauen [aber nicht ZU OFT, sonst wirds merklich langsamer]
|
Re: For-do Schleife mit Sprung
Der Fortschritt wird auch so weitergezeichnet. Was ich brauche ist halt irgendwas, was die Zeit "zählt".
|
Re: For-do Schleife mit Sprung
dann mach deine Anzeige nicht von der Zeit abhängig, sondern von der Anzahl der untersuchten Zahlen
|
Re: For-do Schleife mit Sprung
Die Zeit ist wichtig für mich, damit ich(weil ich ja noch dran rumm progge) weiß, welcher Quellcode besser(schneller) ist. Außerdem hat ja jeder Computer eine andere Geschwindigkeit.
|
Re: For-do Schleife mit Sprung
Zitat:
Zitat:
Noch eine Idee für die for-Schleife mit einem Step:
Delphi-Quellcode:
var
i, ii: Integer; begin for ii := 0 to (Count div 2 - 1) do begin i := ii * 2; // => SHL ist nicht gerade langsam // hier mit i arbeiten end; end; |
Re: For-do Schleife mit Sprung
Zitat:
|
Re: For-do Schleife mit Sprung
Zitat:
|
Re: For-do Schleife mit Sprung
Zitat:
Zum Anzeigen des Fortschritts mit Anzahl der untersuchten Zahlen arbeiten. Ehrlich!!! :mrgreen: :mrgreen: :mrgreen: Oder den ganzen Code zweimal ausführen, damit du beim zweiten mal vorher weißt, wielange er braucht, und davon den Fortschritt abhängig machen kannst. :mrgreen: :mrgreen: :mrgreen: |
Re: For-do Schleife mit Sprung
Zitat:
|
Re: For-do Schleife mit Sprung
Die Differenz der beiden GetTickCount s gibt mir also den Zeitunterschied in 1000stel-Sekunden zurück :o
Sehr schön danke!!!! :thuimb: |
Re: For-do Schleife mit Sprung
Die Auflösung ist nicht ganz 1/1000, sondern liegt etwas darunter.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz