![]() |
Sieb des Eratosthenes
Hallo,
Ich versuche, ein Programm zum Berechnen von Primzahlen zu schreiben, und hätte dazu ein Paar Fragen: Was das Programm können soll: Aus einer Menge an Zahlen von 2 bis n durch das ![]() Dazu habe ich folgenden Code im Internet gefunden:
Delphi-Quellcode:
Das funktioniert insofern, als dass das Programm keine Fehlermeldung angibt und das Programm erfolgreich kompiliert werden kann.
begin
// Eingabe // Verarbeitung for i := 2 to n do zahl[i] := true; p := 2; while p <= n do begin // es werden die Vielfachen von p getrichen v := 2*p; // v ist das 'Vielfache' while v <= n do begin zahl[v] := false; v := v+p; end; // es wird die nächste nicht gestrichene Zahl gesucht p := p+1; if p <= n then weiter := true; // 'weiter' ist ein logischer Schalter while weiter do if (p<=n) and (zahl[p] = false) then p := p+1 else weiter := false; end; Allerdings hat das Programm so noch keinen Nutzen. Meine Fragen wären daher: 1. Wie bringe ich es fertig, dass "n" im Sourcecode die Zahl ist, die man im Editfeld eingegeben hat? Ich habe versucht es unter var zu definieren, hab es aber nicht hingekriegt. 2. Wie kann ich erreichen, dass die berechneten Primzahlen am Ende im Memofeld ausgegeben werden? Gruß, Descole |
AW: Sieb des Eratosthenes
Zitat:
Delphi-Quellcode:
n := StrToInt(Edit1.Text);
Zitat:
Delphi-Quellcode:
for i := 2 to n do if zahl[i] then memo1.lines.add(IntToStr(zahl[i]));
|
AW: Sieb des Eratosthenes
Zitat:
Aber wo genau muss ich
Delphi-Quellcode:
hinschreiben? Unter const funktioniert es nicht, genauso wenig wie bei var.
n:= StrToInt(Edit1.Text)
Und gehört das mit den Memolines zu dem Knopf, wo ich die ganzeSchleife gelagert habe? |
AW: Sieb des Eratosthenes
Bevor Du in Deiner Schleife auf n zugreifst solltest Du es zuweisen / initialiseren. Normalerweise hast Du ein Edit zur Eingabe und einen Button zum Start einer Aktion z.b. Berechnung. In der Ereignisbehandlung des Buttons rufst machst Du dann die Berechnung oder rufst diese, in eine weitere Procedur ausgelagert von dort auf.
Beispiel:
Delphi-Quellcode:
procedure Tform1.ButtonBerechnenClick(Sender : TComponent);
begin // Ggf. vorher überprüfen ob Edit1.Text etwas sinnvolles enthält Siebdeseratosthenes(StrToInt(Edit1.text)); end; procedure TForm1.Siebdeseratosthenes(n : integer); begin .. Dein Code end; |
AW: Sieb des Eratosthenes
Ich glaube, Du solltest einen Anfängerkurs in Delphi absolvieren. Das ist ganz einfahch:
![]() oder ![]() (ist vom gleichen Autor) oder ![]() usw. Einfach mal googeln. |
AW: Sieb des Eratosthenes
Zitat:
|
AW: Sieb des Eratosthenes
Zitat:
Sorry dass ich so viel frage, aber ich bin noch ziemlicher Anfänger :/ |
AW: Sieb des Eratosthenes
Das ist eine von Dir erstellte Prozedur. Dort wo ich "Dein Code.." geschrieben habe solltest Du dann den von Dir aus der Wiki übernommenen Code einfügen. Du kannst diese Prozedure natürlich selber benennen wie Du magst.
|
AW: Sieb des Eratosthenes
Zitat:
|
AW: Sieb des Eratosthenes
Zitat:
So sieht es bei mir im Moment aus:
Delphi-Quellcode:
procedure TForm1.BerechnenClick(Sender: TObject);
begin // Ggf. vorher überprüfen ob Edit1.Text etwas sinnvolles enthält Siebdeseratosthenes(StrToInt(Edit1.text)); end; procedure TForm1.Siebdeseratosthenes(n : integer); var a: real; begin a:= StrtoFloat(Edit1.Text); end; const n=200 ; var zahl : array[2..n] of boolean; p,i,v : integer; weiter : boolean; begin // Eingabe // Verarbeitung for i := 2 to n do zahl[i] := true; p := 2; while p <= n do begin // es werden die Vielfachen von p getrichen v := 2*p; // v ist das 'Vielfache' while v <= n do begin zahl[v] := false; v := v+p; end; // es wird die nächste nicht gestrichene Zahl gesucht p := p+1; if p <= n then weiter := true; // 'weiter' ist ein logischer Schalter while weiter do if (p<=n) and (zahl[p] = false) then p := p+1 else weiter := false; end; end. |
AW: Sieb des Eratosthenes
Zitat:
Delphi-Quellcode:
hat auch nicht geklappt!
n:=StrtoInt(Edit.Text)
Ich kann dir ja meinen Quellcode zeigen:
Delphi-Quellcode:
PS:Bitte schnell antworten! Ich brauche es bis morgen!
procedure TForm1.BerechnenClick(Sender: TObject);
var a: integer; begin if (edtZahl.Text='') then begin lblFehler.Visible:= true end else begin lblFehler.Visible:= false; a:= StrtoInt(edtZahl.Text); if (a < 2) then begin lblFehler2.Visible:= true end else lblFehler2.Visible:= false end; Siebdesratosthenes(StrtoInt(edtZahl.Text)); end; procedure TForm1.Siebdeseratosthenes(n : integer); var zahl : array[2..n] of boolean; p,i,v : integer; weiter : boolean; begin for i := 2 to n do zahl[i] := true; p := 2; while p <= n do begin // es werden die Vielfachen von p getrichen v := 2*p; // v ist das 'Vielfache' while v <= n do begin zahl[v] := false; v := v+p; end; // es wird die nächste nicht gestrichene Zahl gesucht p := p+1; if p <= n then weiter := true; // 'weiter' ist ein logischer Schalter while weiter do if (p<=n) and (zahl[p] = false) then p := p+1 else weiter := false; end; end. |
AW: Sieb des Eratosthenes
-zu jedem "begin" gehört ein "end"
-wenn eine Methode verwendet wird muss sie in der Klasse auch deklariert sein -es gibt keine konstante Arrays mit variablen Größenangaben -der "arbeitende" Teil der Prozedur kann um die Hälfte gekürzt werden |
AW: Sieb des Eratosthenes
Zitat:
|
AW: Sieb des Eratosthenes
Zitat:
|
AW: Sieb des Eratosthenes
Ok, wenn ihr hier schon nach Hilfe schreit ("Bitte schnell antworten! Ich brauche es bis morgen!"), dann müsst ihr euch aber auch mal angewöhnen, nicht nur das linke Ohr vom Eisbären hier zu posten.
Also nur die Methoden aus dem
Delphi-Quellcode:
Teil sind zu wenig.
implementation
Das ist eine komplette Klassen-Definition, mit der wir etwas anfangen können:
Delphi-Quellcode:
Postet also die gesamte Unit und wir werden da mal drüber schauen
interface
type TFoo = class( TObject ) public procedure Bar; // wenn das fehlt, dann gibt es Fehler!!! end; implementation procedure TFoo.Bar; begin // Some code end; |
AW: Sieb des Eratosthenes
Zitat:
Hier ist der Code:
Delphi-Quellcode:
unit Unit1;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls; type { TForm1 } TForm1 = class(TForm) Berechnen: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Image1: TImage; Image2: TImage; Label1: TLabel; Label2: TLabel; Memo1: TMemo; procedure BerechnenClick(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Edit1Change(Sender: TObject); procedure Edit1KeyPress(Sender: TObject; var Key: char); procedure FormCreate(Sender: TObject); procedure Image1Click(Sender: TObject); procedure Image3Click(Sender: TObject); procedure Memo1Change(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin end; procedure TForm1.Image1Click(Sender: TObject); begin end; procedure TForm1.Image3Click(Sender: TObject); begin Showmessage ('http:us.123rf.com/400wm/400/400/speedfighter/speedfighter0907/speedfighter090700086/5179955-silhouette-der-schmetterlinge-fliegen-ber-field-of-flowers.jpg') end; procedure TForm1.Memo1Change(Sender: TObject); begin end; procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char); begin if not (Key in ['0'..'9',#08]) then key:= #0; end; procedure TForm1.Button2Click(Sender: TObject); begin Edit1.Clear; //-> Die Zahlen im Textfeld werden gelöscht Edit1.Text:='200' //-> Im Label für das Ergebnis soll nach dem Löschen nun wieder "Ergebnis" stehen end; procedure TForm1.Button3Click(Sender: TObject); begin Close();//Wenn man auf "schließen" klickt, soll das ganze Programm geschlossen werden end; procedure TForm1.Edit1Change(Sender: TObject); begin end; procedure TForm1.BerechnenClick(Sender: TObject); var a: real; begin a:= StrtoFloat(Edit1.Text); end; const n=200 ; var zahl : array[2..n] of boolean; p,i,v : integer; weiter : boolean; begin // Eingabe // Verarbeitung for i := 2 to n do zahl[i] := true; p := 2; while p <= n do begin // es werden die Vielfachen von p getrichen v := 2*p; // v ist das 'Vielfache' while v <= n do begin zahl[v] := false; v := v+p; end; // es wird die nächste nicht gestrichene Zahl gesucht p := p+1; if p <= n then weiter := true; // 'weiter' ist ein logischer Schalter while weiter do if (p<=n) and (zahl[p] = false) then p := p+1 else weiter := false; end; end. |
AW: Sieb des Eratosthenes
Zitat:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, jpeg, ExtCtrls; type TForm1 = class(TForm) Berechnen: TButton; mAusgabe: TMemo; edtZahl: TEdit; lblPrimzahl: TLabel; lblFehler: TLabel; lblUeberschrift: TLabel; Image1: TImage; Image2: TImage; btReset: TBitBtn; lblFehler2: TLabel; btSchliessen: TButton; procedure edtZahlKeyPress(Sender: TObject; var Key: Char); procedure BerechnenClick(Sender: TObject); procedure btSchliessenClick(Sender: TObject); procedure btResetClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.edtZahlKeyPress(Sender: TObject; var Key: Char); begin if not (Key in ['0'..'9',#08])then begin Key:=#0; Beep; end; end; procedure TForm1.BerechnenClick(Sender: TObject); const n=200 ; var a: integer; zahl : array[2..n] of boolean; p,i,v : integer; weiter : boolean; begin if (edtZahl.Text='') then begin lblFehler.Visible:= true end else begin lblFehler.Visible:= false; a:= StrtoInt(edtZahl.Text); if (a < 2) then begin lblFehler2.Visible:= true end else lblFehler2.Visible:= false end; for i := 2 to n do zahl[i] := true; p := 2; while p <= n do begin // es werden die Vielfachen von p getrichen v := 2*p; // v ist das 'Vielfache' while v <= n do begin zahl[v] := false; v := v+p; end; // es wird die nächste nicht gestrichene Zahl gesucht p := p+1; if p <= n then weiter := true; // 'weiter' ist ein logischer Schalter while weiter do if (p<=n) and (zahl[p] = false) then p := p+1 else weiter := false; end; end; procedure TForm1.btSchliessenClick(Sender: TObject); begin Close(); end; procedure TForm1.btResetClick(Sender: TObject); begin edtZahl.Clear; mAusgabe.Clear; end; end. |
AW: Sieb des Eratosthenes
Zitat:
|
AW: Sieb des Eratosthenes
Zitat:
|
AW: Sieb des Eratosthenes
Also wo ist das Problem?
a) Das Form wird erstellt. b) es gibt einen Button auf den man klickt um die Berechnung zu starten c) es gibt eine Berechnungsroutine für das "SiebdesE" d) diese Routine muß vor ihrem Aufruf definiert sein. Als Erweiterung könnte man den berechneten Array in einem Tmemo oder sonst wo ausgeben. Man könnte für eine variable Obergrenze mit einem dyn. Array arbeiten. Man könnte eine Fortschrittsanzeige einbauen...... aber ohne a-d ist das alles nichts wert. Gruß K-H P.S. Würde mich sehr interessieren, ein gutes Sieb zu sehen. |
AW: Sieb des Eratosthenes
Zitat:
Schau mal das Wichtigste ist den den Algorithmus richtig umzusetzen. Den Algo kannst du quasi 1:1 von Wikipedia abschreiben: ![]() Ok, nächster Schritt: überlege dir was braucht der Algorithmus als Input und was kommt raus? Inputparameter ist N (ein Integer) der Output sind die Primzahlen. Die Ausgabe fehlt bei deinem Code komplett. Du hast einen Input und einen Output und so etwas kann man gut in eine Unterroutine verpacken:
Delphi-Quellcode:
Die Prozedur nützt aber nichts ohne entsprechenden Aufruf:
procedure BerechnePrimZahlen(N:Integer; ausgabe:TStrings);
var gestrichen: array [2..50000] of boolean; // N darf maximal 50000 sein begin { in dem Code auf Wikipedia steht: } // i ist prim, gib i aus print i; ", "; { aber statt dass du print aufrufst machst du das } ausgabe.Add(IntToStr(i)); // Primzahl zur Liste hinzufügen end;
Delphi-Quellcode:
Eigentlich fehlt in deinem Code nur die Ausgabe der Primzahlen (also nur eine Zeile).
procedure TForm1.BerechnenClick(Sender: TObject);
var a:Integer; begin a:= StrtoInt(edtZahl.Text); BerechnePrimZahlen(a{=Parameter N}, mAusgabe.Lines) end; Du müsstest nur
Delphi-Quellcode:
an die richtige Stelle zu schreiben.
mAusgabe.Lines.Add(IntToStr(p));
Welches die richtige Stelle ist, bekommst du raus wenn du deinen Code mit dem Code auf Wikipadia vergleichst. |
AW: Sieb des Eratosthenes
Also mein Lehrer hat uns jetzt mehr Zeit gegeben und die Primzahlen berechnet das Programm jetzt auch.
Das Problem ist jetzt aber, das keine Fehlermeldung mehr angezeigt wird, wenn nichts im Editfeld steht. Auch wenn die Zahl größer ist als der angegebene Bereich (also bei mir array of[2..10001]) zeigt es zwar die Fehermeldung, rechnet aber trotzdem die Primzahlen bis 10006 aus. Wenn man dann 10006 eingibt wird die Fehlermeldung angezeigt und kurz danach stürzt das Programm ab. Hier ist mein Quellcode:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, jpeg, ExtCtrls; type TForm1 = class(TForm) Berechnen: TButton; mAusgabe: TMemo; edtZahl: TEdit; lblPrimzahl: TLabel; lblFehler: TLabel; lblUeberschrift: TLabel; Image1: TImage; Image2: TImage; btReset: TBitBtn; lblFehler2: TLabel; btSchliessen: TButton; lblFehler3: TLabel; procedure edtZahlKeyPress(Sender: TObject; var Key: Char); procedure BerechnenClick(Sender: TObject); procedure btSchliessenClick(Sender: TObject); procedure btResetClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.edtZahlKeyPress(Sender: TObject; var Key: Char); begin if not (Key in ['0'..'9',#08])then begin Key:=#0; Beep; end; end; procedure TForm1.BerechnenClick(Sender: TObject); var a: integer; zahl : array[2..10001] of boolean; p,i,v: integer; weiter : boolean; begin if (edtZahl.Text='') then begin lblFehler.Visible:= true end else begin lblFehler.Visible:= false; a:= StrtoInt(edtZahl.Text); if (a > 10001) then begin ShowMessage('Die Zahl muss kleiner gleich 10001 sein!'); end; if (a < 2) then begin lblFehler2.Visible:= true end else lblFehler2.Visible:= false; end; for i := 2 to a do zahl[i] := true; p := 2; while p <= a do begin // es werden die Vielfachen von p getrichen v := 2*p; // v ist das 'Vielfache' while v <= a do begin zahl[v] := false; v := v+p; end; // es wird die nächste nicht gestrichene Zahl gesucht p := p+1; if p <= a then weiter := true; // 'weiter' ist ein logischer Schalter while weiter do if (p<=a) and (zahl[p] = false) then p := p+1 else weiter := false; end; for i := 2 to a do if zahl[i] then mAusgabe.lines.add(IntToStr(i)) end;// Hier wird dann gesagt das 'weiter' nicht initialisiert wurde procedure TForm1.btSchliessenClick(Sender: TObject); begin Close(); end; procedure TForm1.btResetClick(Sender: TObject); begin edtZahl.Clear; mAusgabe.Clear; end; end. |
AW: Sieb des Eratosthenes
Überleg mal was hier passiert:
Delphi-Quellcode:
Das Programm läuft doch einfach weiter; da fehlt ein
if (edtZahl.Text='') then
begin lblFehler.Visible:= true end else begin lblFehler.Visible:= false; end;
Delphi-Quellcode:
für den Fall dass die Eingabe nicht korrekt ist.
Exit;
|
AW: Sieb des Eratosthenes
Wäre Dein Sourcecode ordentlich formatiert, sollte es eigentlich offensichtlich sein.
Zunächst solltest du mit TryStrtoInt die Obergrenze aus dem Edit übernehme. Dann solltest du die Obergrenze auf Gültigkeit prüfen und dann erst rechnen. Ob Du mit Exit abbrichst oder mit If..else arbeitest ist wahrscheinlich von den Vorlieben Deines Lehrers abhängig. Gruß K-H |
AW: Sieb des Eratosthenes
Zitat:
Hier noch mal der Teil des Codes der verändert wurde:
Delphi-Quellcode:
Sorry, dass ich jetzt noch etwas fragen muss, aber das ist jetzt wirklich die letzte Frage! :)
begin
if (edtZahl.Text='') then begin lblFehler.Visible:= true; Exit; end else begin lblFehler.Visible:= false; a:= StrtoInt(edtZahl.Text); if (a > 10000) then begin lblFehler3.Visible:= true ;Exit; end // Hab dann einfach 'Exit' hinzugefügt! else begin lblFehler.Visible:= false; Bei der Memobox werden die Zahlen alle untereinander angezeigt, also eine Zahl eine Zeile. Ich würde es aber gern so haben, dass in jeder Zeile so viele Zahlen stehen, wie möglich, damit es übersichtlicher wird! Mein Lehrer hat was von nem String gesagt aber ich weiß nicht genau, was er meint... Edit: Schon geklärt!^^ Habs hier gefunden! ![]() |
AW: Sieb des Eratosthenes
Zitat:
mit 'Exit' funktioniert's jetzt auch, hab's einfach vergessen!^^ Aber trotzdem Danke für deine Hilfe! ;) |
AW: Sieb des Eratosthenes
Vielen Dank noch mal an euch alle für eure Hilfe!
|
AW: Sieb des Eratosthenes
Liste der Anhänge anzeigen (Anzahl: 1)
Wie verprochen kommt hier meine "Musterlösung" für das Sieb des Eratosthenes.
Primzahlen bis 10 Mio. zu errechnen benötigt ~ 1 Min. Wer Spass an Mathe und Delphi hat kann ja mal versuchen eine neue Klasse für das ![]() Und dann gibt es auch noch das ![]() |
AW: Sieb des Eratosthenes
Das Sieb von Atkin wurde in der DP bereits umgesetzt. Einfach mal suchen, allerdings nach 'Sieve of Atkins' (nicht Atkin).
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:32 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