Entwickler-Ecke

Sonstiges (Delphi) - Teiler berechnen mit while schleife


newbie333 - Sa 20.06.09 10:55
Titel: Teiler berechnen mit while schleife
Hallo,
bin noch ziemlich unerfahren beim Programmieren. Wir lernen Delphi in der Schule und
sollen nun ein Programm programmieren, welches die Teiler einer Zahl in einem Memofeld ausgeben kann. Leider weiß ich nicht, wie man den "Text" in einem Memofeld verändern kann.
Deshalb hab ichs mit einem Editfeld gemacht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.Button1Click(Sender: TObject);
var n, rechnung: integer;
begin
n := strtoint(edit1.text);
rechnung := 1;
while n mod rechnung = 0 do
begin

edit2.text := inttostr(rechnung);
rechnung := rechnung +1;
end;

end;
end.


Klar ist, dass das Programm so höchstens die 1 als Teiler ausgibt und nicht alle Zahlen.
Wie würde das mit einem Memofeld funktionieren?

Danke schonmal.

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


newbie333 - Sa 20.06.09 11:56

Ok, ich weiß jetzt wie das mit dem memofeld funktioniert, aber das Programm geht leider immer noch nicht..


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);
var n, rechnung: integer;
begin
n := strtoint(edit1.text);
rechnung := 1;
while n mod rechnung = 0 do
begin

Memo1.Lines[0] := inttostr(rechnung);
rechnung := rechnung +1;
Memo1.lines[1]:=inttostr(rechnung);
end;

end;
end.


wenn ich für n 6 eingebe, kommt 6 und 6 raus bei 7 kommt 7 und 7 raus usw.
weiß jemand wo der Fehler liegt?

Und wenn ich jetzt noch mehr als 2 Teiler rausfinden will, nämlich alle, wie mach ich das dann?

Danke!

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


FinnO - Sa 20.06.09 11:57

ich würde an die Aufgabe ein bisschen anders herangehen als du:

Pseudocode:

Quelltext
1:
2:
3:
4:
für Alle Zeilen im Memofeld mache

  wenn Zahl mod MöglicherTeiler = 0 dann
  Teilerliste.Add(MöglicherTeiler)


Wenn du alle Zeilen eines Memos abklappern willst, kannst du so auf sie zugreifen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  i : Integer;
begin
  for i := 0 to Memo1.Lines.Count - 1 do
  Memo1.Lines[i] := 'Hallo';  
end;


newbie333 - Sa 20.06.09 12:14

Den zweiten Teil hab ich verstanden, aber was ist das mit Teilerliste.Add(MöglicherTeiler)?

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

hab das nun so verstanden:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.Button1Click(Sender: TObject);
var n, MoeglicherTeiler, i: integer;
begin
n := strtoint(edit1.text);
MoeglicherTeiler:=1;
if n mod MoeglicherTeiler = 0 then
for i := 0 to Teilerliste.Lines.Count - 1 do
  Teilerliste.Lines[i] := inttostr(MoeglicherTeiler);
 n:=n-1;

end;
end.


kommt aber wieder nur die 1 raus :(

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


bole - Sa 20.06.09 17:32

Hallo Newbee

So wie Ich Dein Problem verstanden habe soll dein Programm alle möglichen ganzzahligen Teiler der Zahl im Edit Feld ins Memo Feld schreiben. Wenn ich dein Problem richtig verstanden habe ist der Preudocode von nicht wirklich korrekt.

Meiner Meinung nach müsste es heissen



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Zahl aus Edit lesen
Teiler auf 1 initalisieren (Division durch 0 erzeugt einen Fehler)

Für jeden Teiler kleiner der Zahl mache (Schleifenanfang)
   Ist Zahl MOD Teiler = 0 dann Teiler ins Memo schreiben
   Teiler erhöhen
(Schleifenende)


Ich hoffe ich habe Dich richtig verstanden und der Pseudocode hilft Dir Weiter.

Gruss
Reto


newbie333 - Sa 20.06.09 21:20

Ok, für den ersten Teiler klappt das nun einwandfrei.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.Button1Click(Sender: TObject);
var n, Teiler: integer;
begin
n := strtoint(edit1.text);
Teiler:=1;
while Teiler < n do
begin
if n mod teiler = 0 then
Memo1.lines[0]:= inttostr(Teiler);
Teiler:= Teiler+1;
end;



wie mache ich das mit den restlichen? :)
Danke!

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


FinnO - Sa 20.06.09 21:36


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.Button1Click(Sender: TObject);
var n, Teiler: integer;
begin
n := strtoint(edit1.text);
Teiler:=1;
while Teiler < n do
begin
if n mod teiler = 0 then
Memo1.lines[0]:= inttostr(Teiler); // hier gibst du nur den ersten Teiler aus
//besser:
Memo1.Lines.Add(IntToStr(Teiler));
Teiler:= Teiler+1;
end;


newbie333 - So 21.06.09 11:45

Das funktioniert nun schon besser, hat aber immer noch Fehler..

Zum Einen bleibt ganz oben im Memofeld der Name des Memofeldes stehen
und zum Anderen bleiben die Zahlen vom vorherigen Teiler auch noch stehen..
ich habs versucht mit Memo1.lines.clear aber dann werden überhaupt keine Zahlen mehr ausgegeben..
Weiß jemand wie man den Fehler beheben kann?

der aktuelle Quelltext ist nun so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.Button1Click(Sender: TObject);
var n, Teiler: integer;
begin
n := strtoint(edit1.text);
Teiler:=1;
while Teiler < n do
begin
if n mod teiler = 0 then
Memo1.Lines.Add(IntToStr(Teiler));
Teiler:= Teiler+1;
end;


Danke für die Hilfe.

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


jfheins - So 21.06.09 13:25

Memo1.lines.clear ist schon richtig - wo hast du es denn hingeschrieben?


newbie333 - So 21.06.09 14:29

Ja, da liegt glaub ich auch das Problem..

Delphi-Quelltext
1:
2:
3:
Teiler:= Teiler+1;
end;
Memo1.lines.clear;

hier hatte ichs..

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


jfheins - So 21.06.09 14:35

Das ist natürlich nur bedingt sinnvoll, das memo zu leeren, nachdem du das interessante reingeschrieben hast - mehr Sinn macht es, wenn du das Memo löscht bevor du deine Teiler reinschreibst ;)


newbie333 - So 21.06.09 14:48

Okay, ergibt Sinn ;)
Funktioniert auch, aber irgendwie kommen bei 8 folgende Teiler raus:
4,5,6,7
bei 3: 1,2
was ist denn dieses mal noch falsch? :(


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.Button1Click(Sender: TObject);
var n, Teiler: integer;
begin
n := strtoint(edit1.text);
Teiler:=1;
while Teiler < n do
begin
if n mod teiler = 0 then
Memo1.Lines.Clear;
Memo1.Lines.Add(IntToStr(Teiler));
Teiler:= Teiler+1;
end;


Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


Jakob_Ullmann - So 21.06.09 15:20

Logisch. Mal ein paar Dinge, von denen ich glaube, dass du sie noch nicht verstanden hast.

Memo1.Lines ist -- einfach gesagt -- der Inhalt des Memos (als StringListe). Jede Zeile ist ein String für sich. Das heißt also bei:


Quelltext
1:
2:
3:
hallo
welt
12345


gilt:


Delphi-Quelltext
1:
2:
3:
Memo1.Lines[0] = 'hallo';
Memo1.Lines[1] = 'welt';
Memo1.Lines[2] = '12345';

(analog dazu gilt auch: StrToInt(Memo1.Lines[2]) = 12345;)

Memo1.Lines.Clear löscht alle Zeilen!
Memo1.Lines.Add('das ist ein string'); fügt die Zeile das ist ein string hinten dazu (als letzte Zeile).


Delphi-Quelltext
1:
2:
3:
if bedingung then
  tue1;
tue2;


heißt (unabhängig davon, wie weit tue2 eingerückt ist):


Quelltext
1:
2:
3:
4:
falls bedingung wahr ist:
  führe nur dann tue1 aus;

führe unabhängig von bedingung tue2 aus;


dagegen:


Delphi-Quelltext
1:
2:
3:
4:
5:
if bedingung then
begin
  tue1;
  tue2;
end;


bedeutet:


Quelltext
1:
2:
3:
falls bedingung wahr ist:
  führe nur dann tue1 aus;
  führe auch nur dann tue2 aus;


Und jetzt, warum ich dir das sage:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.Button1Click(Sender: TObject);
var n, Teiler: integer;
begin
n := strtoint(edit1.text);
Teiler:=1;
while Teiler < n do
begin
if n mod teiler = 0 then
Memo1.Lines.Clear;
Memo1.Lines.Add(IntToStr(Teiler));

Teiler:= Teiler+1;
end;


Merkst du was?? Wenn ein Teiler gefunden wurde, wird die Liste gelöscht. Und es werden alle Werte von 1 bis n der Liste hinzugefügt. Das erklärt auch deine Ausgaben. Hast du eine Idee, wo das Memo1.Lines.Clear hin muss?

Und bitte rücke deinen Code ein. Das verschafft auch oft Klarheit:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.Button1Click(Sender: TObject);
var
  n, Teiler: integer;
begin
  n := strtoint(edit1.text);
  Teiler:=1;
  while Teiler < n do
  begin
    if n mod teiler = 0 then
      Memo1.Lines.Clear;
    Memo1.Lines.Add(IntToStr(Teiler));
    Teiler:= Teiler+1;
  end;


Da wird es auch offensichtlich.

edit: Im Übrigen eignet sich eine for-Schleife hier besser.


newbie333 - So 21.06.09 15:35

tut mir leid, ich verstehs nicht..
müsste ich dann bei if noch begin und end einfügen?
und wo muss das Memo1.lines.Clear hin?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var
 n, Teiler: integer;
begin
 n := strtoint(edit1.text);
 Teiler:=2;

 while Teiler < n do
 begin
   if n mod teiler = 0 then
   begin
   Memo1.lines.clear; // hier löscht es das Memofeld nachdem ein Teiler gefunden wurde
   Memo1.Lines.Add(IntToStr(Teiler)); // und fügt diesen Teiler hier ein, stimmt das nicht?
   Teiler:= Teiler+1;
   end;

 end;


Jakob_Ullmann - So 21.06.09 15:46

deine Quellcode-Interpretation ist richtig. Aber sie erfüllt nicht die Aufgabenstellung.

1.) Der Teiler sollte unabhängig von der Bedingung erhöht werden. Ansonsten verfängst du dich in geschätzten 95% der Fälle in einer Endlosschleife (halt abhängig vom Zahlenbereich, ansonsten können wir das gut auf 100% anheben). :wink: Das Problem gäbe es übrigens mit einer for-Schleife nicht.
2.) Es sollte vor der gesamten Rechnerei gelöscht werden, denn es sollen ja alle Teiler gefunden werden.

Dann sollte es klappen.

Noch als Tipp, aber nicht notwendig: Statt Teiler := Teiler + 1 kannst du auch einfach inc(Teiler); schreiben, wenn du willst.


newbie333 - So 21.06.09 15:57

For-Schleifen hatten wir leider noch nicht, deshalb hab ich davon keine Ahnung.

Ich glaub ich habs soweit verstanden:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);
var
 n, Teiler: integer;
begin
 n := strtoint(edit1.text);
 Teiler:=1;
Memo1.lines.clear;
 while Teiler < n do
 begin
   if n mod teiler = 0 then
   Memo1.Lines.Add(IntToStr(Teiler));
Teiler:= Teiler+1;
 end;
end;
end.

Allerdings wird nie die letzte Zahl angegeben, also bei 5 die 5, bei 7 die 7 usw..
wie kann ich das denn machen? :)

Vielen Dank!

Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.


Marc. - So 21.06.09 16:04

user profile iconnewbie333 hat folgendes geschrieben Zum zitierten Posting springen:
Allerdings wird nie die letzte Zahl angegeben, also bei 5 die 5, bei 7 die 7 usw..
wie kann ich das denn machen? :)


Delphi-Quelltext
1:
while Teiler <= n do                    


jfheins - So 21.06.09 16:04

Du müsstest aus dem < ein <= machen ...


newbie333 - So 21.06.09 16:07

Juhu es funktioniert endlich :D Dankeschön!


bole - So 21.06.09 16:08

Hoi Newbie

Du musst die Bedingung der While Schleife ändern. Statt 'kleiner als' 'kleiner Gleich als', dann kommt auch die letzte Zahl.

Die Bedingung 'kleiner als' bedeutet ja wenn die Zahl gleich dem Teiler ist wird die Schleife abgebrochen. Da die Prüfung der Bedingung in der While Schleife vor den Schleifendurlauf gemacht wird bricht sie ab.

Gruss
Bole


newbie333 - So 21.06.09 18:53

Und nochmal...

Als nächstes sollen wir ein Programm erstellen, das prüft ob eine Zahl Primzahl ist oder nicht. Ich überlege gerade ob das mit diesem Programm geht, denn wenn im Memofeld nur die zahlen 1 und n stehen, müsste das ja theoretisch dann eine Primzahl sein.
Würde das gehen?


FinnO - So 21.06.09 20:00

Neue Frage -> Neuer Thread...


newbie333 - So 21.06.09 20:42

Es ist aber im Prinzip eine Erweiterung von diesem Programm ;)


bole - So 21.06.09 21:05

Hallo Newbie

Benutz die Suche, es gibt viele Threds die sich mit dem Problem beschäftigen...


newbie333 - Di 23.06.09 13:33

Hab ich schon, hilft mir leider nicht weiter, weil die meisten Dinge benutzen, die wir noch nicht gelernt haben ;)


jaenicke - Di 23.06.09 14:58

Dann stell doch dazu Fragen was du nicht verstehst. Ich meine woher sollen wir denn wissen was an diesen Quelltexten das Problem ist? :nixweiss:

Prinzipiell gibts da ja einfache Algorithmen wie das Sieb des Erathosthenes [http://de.wikipedia.org/wiki/Sieb_des_Eratosthenes], das mit einem Array auskommt, usw.