Pascal-Programm zur ggT-Prüfung

Alle Arten von Programmen und Anwendungen: Egal ob Betriebssysteme, Systemtools, Grafikbearbeitung, Musikeditoren oder Textverarbeitung. Hier wird über alles gesprochen.
Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
Do 16. Sep 2004, 15:12 - Beitrag #1

ggT prüfung von der Logik her

M0in,

also ich hatte ja mein hübsches Turbo Pascal Proq das die Teiler ausgab, das hab ich soweit umgebaut dass es in der schleife jeden teiler darauf überprüfte, ob er auch ein teiler der anderen zahl war und ob das der ggT war.

Ich hab meine diskette auf meinen PC gelegt ( warum hat die schule keine speichersticks aber neue kisten?) und alles futsch.

Also neuanfang, hab des Prog ganz anders angesetzt. Da aber ne woche vergangen ist hab ich vergessen wie ich das gemacht hab mit dem überprüfen des Teilers!

Ich wollte diesmal eine extra prozedur aufrufen, die den Teiler übeprüft.
Hier mein Code, die auskommentierten Stellen machen probs.

$this->bbcode_second_pass_code('', '
PROGRAM teiler_daheim;
USES wincrt;
VAR z,n,teiler,uebertrag: INTEGER;
ch : char;


Procedure Eingabe;
Begin
clrscr;
z:=0;
teiler:=0;
writeln(' Gib den Zähler ein!');
readln(z);
writeln(' Gib den Nenner ein!');
ReadLn(n);
End;

{Procedure pruefe;
Begin
uebertrag:=z MOD teiler;
IF (uebertrag MOD n)=0 THEN WRITELN('w00t');
end;}


Procedure Verarbeitung;
Begin
REPEAT
For teiler:= 1 to z do
Begin
IF (z MOD teiler)=0 {THEN pruefe} THEN{bzw. ELSE} writeln (teiler,' ist ein Teiler von ',z,'!');

End;
WRITELN('Neue Werte? (j/n) '); ch := readkey;
UNTIL ch = 'n';
WRITELN;
WRITELN('Programm beendet!');
End;


Begin
Eingabe;
Verarbeitung;
End.
')


Ausserdem Macht die Abfrage auch Probleme, wenn ich j eingebe, wiederholt er das vorherige exakt, er fragt nicht nach neuen Werten!

Könntet ihr mir weiterhelfen?

blobbfish
Listenkandidat
Lebende Legende

Benutzeravatar
 
Beiträge: 3022
Registriert: 26.01.2003
Do 16. Sep 2004, 18:35 - Beitrag #2

Puh, so ganz bin ich nicht durchgestiegen, aber zu deinem Problem, dass er bei "j" einfach dieselben Werte nimmt und weiterrechnet habe ich eine einfach Lösung: Die Werteeingabe wird einfach übersprungen. Sie gehört an den Anfang der "repeat ... until"-Schleife. Desweiteren kannst du du die Prozedur "Verarbeite" als Hauptprogramm laufen lassen, also das Prozedur entfernen und unten das kleine Brüchel entfernen.

Im Prinzip willst du nur den Zähler überprüfen, was an sich auch sinn macht, das geht aber auch einfacher:

[font=courier new]IF z mod teiler = 0 THEN
WRITELN('Die Zahl ',teiler,' ist ein Teiler von ',z)
ELSE WRITELN('Die Zahl ',teiler,' ist ein kein Teiler von ',z);[/font]

Zur Erklärung: Teiler ist ein Teiler von z, wenn sie teilbar sind, das heißt der Rest 0 ergibt, das heißt, dass die Anweisung "Mod" ebenfalls 0 zurückliefern muss. Tut sie es nicht, ist es kein Teiler.

Ich hoffe die Korrektur stimmt soweit, hab das jetzt nicht in meinen Delphi-Compiler reingehackt.

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
Do 16. Sep 2004, 19:57 - Beitrag #3

Die Teiler hab ich ja ohne pRobleme gecoded, nur ich möchte halt jedes mal, wenn ein Teiler für den zähler errechnet wird, diesen überprüfen, ob es der ggT für z und n ist.

BTW, Das prob mit der Eingabe hab ich so gelöst:

$this->bbcode_second_pass_code('', 'PROGRAM teiler_daheim;
USES wincrt;
VAR z,n,teiler,uebertrag: INTEGER;
ch : char;


Procedure Eingabe;
Begin
clrscr;
z:=0;
teiler:=0;
writeln(' Gib den Zähler ein!');
readln(z);
writeln(' Gib den Nenner ein!');
ReadLn(n);
End;

{Procedure pruefe;
Begin
uebertrag:=z MOD teiler;
IF (uebertrag MOD n)=0 THEN WRITELN('w00t');
end;}


Procedure Verarbeitung;
Begin
REPEAT
eingabe;
For teiler:= 1 to z do
Begin
IF (z MOD teiler)=0 {THEN pruefe} THEN{bzw. ELSE} writeln (teiler,' ist ein Teiler von ',z,'!');



End;
WRITELN('Neue Werte? (j/n) '); ch := readkey;
UNTIL ch = 'n';
WRITELN;
WRITELN('Programm beendet!');
End;


Begin
Verarbeitung;
End.
')

blobbfish
Listenkandidat
Lebende Legende

Benutzeravatar
 
Beiträge: 3022
Registriert: 26.01.2003
Sa 18. Sep 2004, 23:57 - Beitrag #4

Wenn ich das richtig sehe hast du doch einen Bruch oder? wie willst du den ggT eines Bruches finden? Normalerweise braucht man dazu doch zwei Zahlen ...

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
So 19. Sep 2004, 11:21 - Beitrag #5

lol, bruch lol

Zwei zahlen, wie ich sie nenne ist nun total lachs....

Mein ziel ist es halt , jeden teiler daraufhin zu überprüfen, ob es der ggt ohne den ggt vorher auszurechnen!

Nur hab ich vergessen wie ich das gemacht hab und es fällt mir nimm0 ein!

blobbfish
Listenkandidat
Lebende Legende

Benutzeravatar
 
Beiträge: 3022
Registriert: 26.01.2003
So 19. Sep 2004, 12:31 - Beitrag #6

Klar nur wenn ud den Quelltext nicht erläuterst, was man immer machen sollte, sei er noch so klein, muss ich wohl das aus dem text rausziehen, was er hergibt und "Nenner und zähler" assoziere ich i.d.R. mit einem Bruch. Aber da ich jetzt weiß, was du machen willst sehe ich mich auch in der Lage, dir sinnvoll zu helfen. Variablenbennung ist an sich sehr wichtig, besonders wenn man an einem umfangreichen Projekt arbeitet, an dem mehrere Leute arbeiten. Da kommt es schnell zu Missverständnissen und 1000 oder gar 10000 oder mehr Zeilen zu debuggen macht keine Freude ... glaub mir ;)

Spontan machst du eine Schleife, in dieser Schleife sammelst du die Teiler der 1. Zahl, sie läuft von 1 bis a (a ist die erste Zahl). Ist die Zahl n dann ein Teiler von a prüfst du ganz einfach, ob sie auch ein Teiler von b ist. Ist sie ein Teiler von b, Zahl speichern und die Schleife dennoch weiterlaufen lassen, ist sie kein Teiler, die Schleife einfach weiterlaufen lassen.

Vorher setzt du meinetwegen noch die Variable für die Speicherung des ggT auf 0 oder -1. Ist die Schleife fertig kannst du angeben, ob es einen ggT gibt und welcher dieser ist. Steht die Variable auf -1, dann gibt es keinen. Du musst die Variable aber vorher auf -1 setzten, Pascal-Compiler haben die Angewohnheit zum Programmstart irgendwas reinzuschreiben.

Ich hoffe damit ist dir geholfen, wie immer hab ich das nicht ausprobiert ;)

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
So 19. Sep 2004, 14:55 - Beitrag #7

Original geschrieben von blobbfish

Spontan machst du eine Schleife, in dieser Schleife sammelst du die Teiler der 1. Zahl, sie läuft von 1 bis (a ist die erste Zahl). Ist die Zahl n dann ein Teiler von a prüfst du ganz einfach, ob sie auch ein Teiler von b ist. Ist sie ein Teiler von b, Zahl speichern und die Schleife dennoch weiterlaufen lassen, ist sie kein Teiler, die Schleife einfach weiterlaufen lassen.

Vorher setzt du meinetwegen noch die Variable für die Speicherung des ggT auf 0 oder -1. Ist die Schleife fertig kannst du angeben, ob es einen ggT gibt und welcher dieser ist. Steht die Variable auf -1, dann gibt es keinen. Du musst die Variable aber vorher auf -1 setzten, Pascal-Compiler haben die Angewohnheit zum Programmstart irgendwas reinzuschreiben.

Ich hoffe damit ist dir geholfen, wie immer hab ich das nicht ausprobiert ;)


oh, ich hab das wieder nur halb kapiert, sonntagsarbeit suxx...

also ist in deinem post:

a=z
n=n


aber was ist b? kannst du mir das so in pascal aufschreiben?

blobbfish
Listenkandidat
Lebende Legende

Benutzeravatar
 
Beiträge: 3022
Registriert: 26.01.2003
So 19. Sep 2004, 15:12 - Beitrag #8

Hui, so schwer ist das doch nicht. Den Code kannst du dir selber ausdenken, ich benutzte Delphi, da gibt's kleine aber feine Unterschiede, außerdem gehöre ich nicht zu der Sorte Leuten, die anderer Leuts Hausaufgaben oder ähnliches machen.

Also nochmal zum mitschreiben[denken]:
Du setzt eine Variable zum Speichern des ggT zu Prozedurbeginn auf -1. Dann beginnt du mit einer Schleife, die läuft von 1 bis zur Zahl a. Du zählst dabei die Variable n hoch. Du baust eine abfrage ein, die prüft ob n ein Teiler von a ist. Ist dies der Fall, so teilst du die Zahl b (Das ist die zweite Zahl, die der Benutzer eingibt) durch die Zahl n und stellst nun fet ob n ein Teiler von b ist. Ist n ein Teiler von b, dann überschreibst du die Speichervariable für den ggT mit der Zahl n.

Es gibt jetzt 2 Möglichkeiten: Die Speichervariable für den ggT ist -1. Die beiden Zahlen haben keine gemeinsamen und daher auch keinen ggT. Beispiel ist 7 und 9. Im anderen Fall ist die Variable ungleich -1, es existiert ein ggT und der ist auch gleich gespeichert.

PS.: Beim Programmieren kommt es nicht darauf an, die Befehle zu wissen und so weiter, sondern sich ein sinnvolles Konzept zu überlegen. Flussdiagramme sowie Struktogramme sind da sehr hilfreich. Benutzte ich auch gelegentlich.

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
So 19. Sep 2004, 16:35 - Beitrag #9

Original geschrieben von blobbfish
.

Also nochmal zum mitschreiben[denken]:
Du setzt eine Variable zum Speichern des ggT zu Prozedurbeginn auf -1. Dann beginnt du mit einer Schleife, die läuft von 1 bis zur Zahl a. Du zählst dabei die Variable n hoch. Du baust eine abfrage ein, die prüft ob n ein Teiler von a ist. Ist dies der Fall, so teilst du die Zahl b (Das ist die zweite Zahl, die der Benutzer eingibt) durch die Zahl n und stellst nun fet ob n ein Teiler von b ist. Ist n ein Teiler von b, dann überschreibst du die Speichervariable für den ggT mit der Zahl n.

Es gibt jetzt 2 Möglichkeiten: Die Speichervariable für den ggT ist -1. Die beiden Zahlen haben keine gemeinsamen und daher auch keinen ggT. Beispiel ist 7 und 9. Im anderen Fall ist die Variable ungleich -1, es existiert ein ggT und der ist auch gleich gespeichert.

PS.: Beim Programmieren kommt es nicht darauf an, die Befehle zu wissen und so weiter, sondern sich ein sinnvolles Konzept zu überlegen. Flussdiagramme sowie Struktogramme sind da sehr hilfreich. Benutzte ich auch gelegentlich.


son quark, da überleg ich mir lieber selbst.

was ist a bei dir? Wenn wir die gleichen variablenb verwenden würden wär allez einfacher.

Du zählst dabei die Variable n hoch

wat?

blobbfish
Listenkandidat
Lebende Legende

Benutzeravatar
 
Beiträge: 3022
Registriert: 26.01.2003
So 19. Sep 2004, 16:58 - Beitrag #10

Na dann denk dir was aus. Allerdings solltest du meine Methode nicht als Quark bezeichnen. Sicher geht das auch kürzer, aber optimieren kann man, nachdem man ein umgesetztes funktionierendes Konzept hat.

a ist wie einige Posts weiter oben erläutert die erste Zahl die der User eingibt.
Aber nochmal für dich:
a : Nenner
b : zäaehler
n : n
Meinetwegen kannst du a und b auch vertauschen, das sei dir überlassen.

Variable hochzählen heißt, sie pro Iteration um 1 zu erhöhen, zumindest im Regelfall.

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
So 19. Sep 2004, 18:14 - Beitrag #11

na , geht doch, dann hab ich ja alles :

aber dennoch kommt dabei nur mist raus:

$this->bbcode_second_pass_code('', '
Procedure pruefe;
Begin
IF (z MOD w)=0 THEN
IF (n MOD w)=0 THEN ggT:=w ELSE WRITELN;
end;
')

blobbfish
Listenkandidat
Lebende Legende

Benutzeravatar
 
Beiträge: 3022
Registriert: 26.01.2003
So 19. Sep 2004, 19:18 - Beitrag #12

Zeig doch den ganzen Quelltext, weiß ja keiner, was sonst gemacht wurde.

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
So 19. Sep 2004, 19:33 - Beitrag #13

ach gott, ich dreh noch durch ( nich durch dich), ich bau das noch als funktion ein und gut is!

Ich will aber ne Proc, man, ich peils einfach nit.

Sag mir mal was dieser ausdruq bedeutet:

ggt(b, a mod b)

Zum Quelltext:

Heraus komt nur Bock mist, er zeigt nur die _nicht_teiler von der ersten zahl an, sonst nix *heul*!

$this->bbcode_second_pass_code('', '
PROGRAM teiler_daheim;
USES wincrt;
VAR q,w,r,g,ggT,z,n,teiler,uebertrag: WORD;
ch : char;


Procedure Eingabe;
Begin
clrscr;
WRITELN('Willkommen bei teiler_daheim von Dawid Golebiewski (alle Rechte vorbehalten)');
z:=0;
teiler:=0;
WRITELN('');
writeln('Gib den Zähler ein!');
readln(z);
writeln('Gib den Nenner ein!');
ReadLn(n);
IF z=0 THEN WRITELN('Bitte gescheite Zahlen eingeben!');
IF z=0 THEN HALT(0);
IF n=0 THEN WRITELN('Bitte gescheite Zahlen eingeben!');
IF n=0 THEN HALT(0);
End;

{Procedure gT;
Begin
ggT:= 1;
IF z=0 THEN ggT:=n ELSE
IF n=0 THEN ggT:=z;
IF (z MOD N)=0 THEN ggT:=n;




WRITELN;
WRITELN('Der ggT von ',z,' und ',n,' ist: ',ggT);
WRITELN;


end;}

Procedure pruefe;
Begin
IF (z MOD w)=0 THEN
IF (n MOD w)=0 THEN ggT:=w ELSE WRITELN;
end;


Procedure Verarbeitung (z :WORD);
Begin
w:=1;
For teiler:= w to z do
Begin

IF (z MOD teiler)=0 THEN pruefe ELSE {bzw. ELSE} writeln (teiler,' ist ein Teiler von ',z,'!');



End;
End;


Begin
REPEAT
eingabe;
Verarbeitung (z);
WRITELN('Neue Werte? (j/n) '); ch := readkey;
UNTIL ch = 'n';
WRITELN;
WRITELN('Programm beendet!');
End.
')

blobbfish
Listenkandidat
Lebende Legende

Benutzeravatar
 
Beiträge: 3022
Registriert: 26.01.2003
So 19. Sep 2004, 20:03 - Beitrag #14

$this->bbcode_second_pass_code('', 'program ggT;

uses
wincrt

var
a,b,n,swap : integer;
ch : char;

begin
repeat
swap := -1;
clrscr;
writeln('Zahl 1 eingeben');
readln(a);
writeln('Zahl 2 eingeben');
readln(b);

{ Eigentlicher Programmcode }
n := 0;
repeat
n := n + 1;
if a mod n = 0 then // Prüft ob n Teiler von a ist
if b mod n = 0 then// Prüft ob n Teiler von b ist
swap := n; // Ist n ein Teiler ist es der aktuelle ggT, kann größer werden, muss aber nicht, Die If-Abfragen kann man auch noch komprimieren mittels logischem Operator, aber nicht zwingend notwendig
until (n = a) OR (n = b); // Durch logisches Oder wird CPU-Zeit gespart, da bei der kleineren Zahl abgebrochen wird

if swap = -1 then
writeln('Es gibt keinen ggT')
else
writeln('der ggT ist: ',swap);
{ eigentlicher Programmcode Ende }
writeln('Neue Werte? (j/n) ');
ch := readkey;
until ch = 'n';
end.')

So, das hab ich grademal geschireben. Ich steig bei deinem Quelltext nur komich durch. Ein Fehler war zum Beispiel, dass du "teiler" erhöht hast, aber mit "w" die Zahlen durchprobiert hast, das kann freilich nicht gehen.

Sollte Pascal die // nicht als Kommentare erkennen einach durch { und } ersetzten oder cutten. Die Eingabe hab ich vereinfacht, weil ich nicht testen wollte, ob das unter Delphi-Konsole auch so geht.

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
So 19. Sep 2004, 20:32 - Beitrag #15

Ich habe mein Prob schon in griff bekommen, bin es anders angegangen, probiere deins aber auch aus.

Dein Proq aber gibt nicht die teiler aus, es berechnet nur den ggT, AFAIU?


EDIT: hat sich erledigt...

Noriko
Moderator
Moderator

Benutzeravatar
 
Beiträge: 5864
Registriert: 15.11.2001
So 19. Sep 2004, 20:41 - Beitrag #16

ich würde sagen "3 div 5"
ich habe es auich mal geshcirben, musste mir dafür sogar TP nochma beibringen und habe mit diversen verbesserungen vielleicht 30 min gebraucht.
$this->bbcode_second_pass_code('', '
program bla;
var z1,z2,n,gT:longint;
fin:char;
begin
repeat
begin
z1:=0;
z2:=0;
n:=1;
Write('Zahl 1: ');
readln(z1);
Write('Zahl 2: ');
readln(z2);
repeat
begin
if (z1 MOD n=0) AND (z2 MOD n=0)
then
begin
gT:=n;
n:=n+1;
writeln(gT,' ist ein Teiler von ',z1,' und ',z2)
end
else
n:=n+1;
end
until (n=z1+1) OR (n=z2+1);
writeln;
write('der gr”sste gemeinsame Teiler von ',z1,' und ',z2,' ist ',gT);
readln;
Writeln('Programm beenden j/n?');
readln(fin);
end
Until fin='j';
end.
')

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
So 19. Sep 2004, 20:46 - Beitrag #17

hehe, es zeichnet sich ab: Jeder hat seinen eingenen Code-Style...


Also ich habs geschafft, falls ihrs sehen wollt, nur bescheid sagen...

blobbfish
Listenkandidat
Lebende Legende

Benutzeravatar
 
Beiträge: 3022
Registriert: 26.01.2003
So 19. Sep 2004, 20:54 - Beitrag #18

Jo mach mal, immer her damit.

Alle Teiler kann ich auch ausgeben, würde die Elegant in einem array speichern, der an die anzahl Teiler angepasst wird :)

Daddy-Dennis
Very Good Newbie
Very Good Newbie

 
Beiträge: 40
Registriert: 16.09.2004
So 19. Sep 2004, 22:09 - Beitrag #19

$this->bbcode_second_pass_code('', '
PROGRAM teiler_daheim;
USES wincrt;
VAR prod,kgv,q,rest,b,w,a,ggT,z,n,teiler: WORD;
ch : char;


Procedure Eingabe;
Begin
clrscr;
WRITELN('Willkommen bei teiler_daheim von Dawid Golebiewski (alle Rechte vorbehalten)');
z:=0;
teiler:=0;
WRITELN('');
writeln('Gib den Zähler ein!');
readln(z);
writeln('Gib den Nenner ein!');
ReadLn(n);
IF z=0 THEN WRITELN('Bitte gescheite Zahlen eingeben!');
IF z=0 THEN HALT(0);
IF n=0 THEN WRITELN('Bitte gescheite Zahlen eingeben!');
IF n=0 THEN HALT(0);
End;

Procedure gT;
Begin
ggT:=1;
a:=z;
b:=n;
IF z=0 THEN ggT:=n ELSE
IF n=0 THEN ggT:=z;
IF (z MOD N)=0 THEN ggT:=n;

while b<>0 do
begin
rest:=a mod b;
a:=b;
b:=rest;

ggT:=a;

End;



WRITELN;
WRITELN('Der ggT von ',z,' und ',n,' ist: ',ggT);
WRITELN;

end;

Procedure der_kgV;
Begin
Prod:=n*z;
kgV:=(Prod DIV ggT);
WRITELN;
WRITELN('Das kgV von ',z,' und ',n,' ist: ',kgV);
WRITELN;
End;



Procedure Verarbeitung (z :WORD);
Begin
w:=1;
For teiler:= w to z do
Begin

IF (z MOD teiler)=0 THEN writeln (teiler,' ist ein Teiler von ',z,'!');



End;
End;


Begin
REPEAT
eingabe;
Verarbeitung (z);
gt;
der_kgv;
WRITELN('Neue Werte? (j/n) '); ch := readkey;
UNTIL ch = 'n';
WRITELN;
WRITELN('Programm beendet!');
End.
')

vogt31337
Junior Member
Junior Member

 
Beiträge: 69
Registriert: 25.06.2003
Mo 20. Sep 2004, 15:47 - Beitrag #20

$this->bbcode_second_pass_code('', '
function ggt(a,b:integer):integer;
var n:integer;
begin
n:=1;
ggt:=1;
repeat
if ((a mod n =0) AND (b mod n=0)) then ggt := n;
until n = max(a,b) div 2;
end;
')
man bemerke die 5 wichtigen Zeilen :)

Nächste

Zurück zu Software

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 8 Gäste

cron