Bruchkürzung... Brauche dringend Hilfe!
-
hy leute!
und zwar habe ich von meiner schule folgendes problem gestellt bekomm. ich soll ein programm erstelln, welches brüche soweit wie möglich kürzen kann. das was ich bisher hinbekomm hab ist folgendes:
-------------------------------------------------------------------------------//Bruchkürzung Matthias Walter
#include<iostream.h>
void kurz(int &zaehler, int &nenner);
void main()
{int zaehler;
int nenner;
cout<<"Bitte Zähler eingeben: ";
cin >>zaehler;
cout<<"Bitte Nenner eingeben: ";
cin >>nenner;
kurz(zaehler, nenner);
cout<<"Ergebnis: "<<zaehler<<"/"<<nenner<<endl<<endl;
}void kurz (int &zaehler, int &nenner)
{
int temp, temp2;
if (nenner>zaehler)
{temp=nenner%zaehler;
if (temp==0)
{
temp=zaehler/zaehler;
nenner=nenner/zaehler;
zaehler=temp;}
else
{
const int temp1 = zaehler;do
{zaehler=zaehler-1;
temp=nenner%zaehler;
temp2=temp1%zaehler;
}
while (temp2 !=0 && temp !=0);nenner=nenner/zaehler;
zaehler=zaehler/zaehler;
}
}else
{
cout<<"..."; //soweit bin ich noch nich, daher nur ne sinnlos ausgabe
}}
-------------------------------------------------------------------------------
soweit so gut. irgendwie hab ich aber folgendes problem, dass in der verschachtelten else-anweisung nur müll hrausbekomme. Irgendwie rechnet der Modulus falsch bzw. die Schleifenprüfung prüft nur einen Parameter.
Bsp.: Ich habe einen Bruch: 8/12
So könnte man den auf 2/3 kürzen. Als Ergebnis kommt aber 1/2. Den Fehler hab ich auch schon gefunden, weiß aber nicht wie ich den beseitigen soll. In der Schleifenprüfung soll ja beides 0 sein (vom Modulus). Temp2 ist aber bei dem Beispiel 2 und trotzdem geht er aus der Schleife raus....

Wäre echt cool, wenn mir schnellstmöglich jemand von euch helfen könnt.
thx schon mal im voraus....
-
Vielleicht solltest du deine komplette Rechnung mal überdenken (Stichwort "kleinster gemeinsamer Teiler")
-
warum "kleinster"? ich suche ja den größten gemeinsamen teiler
-
MW_ICEMAN schrieb:
warum "kleinster"? ich suche ja den größten gemeinsamen teiler
Es ist wohl offensichtlich, dass CStoll ggt meint, und nicht 1.
-
OK, dann nimmst du halt den größten gemeinsamen Teiler

(auf jeden Fall gibt es da eine schnellere Methode zur Berechnung als deine Schleifenkonstruktion)
-
ja wie jetzt...?! die rechnung stimmt doch aber.... was soll daran falsch sein? erst wird geprüft welche zahl größer ist von beiden. im falle des nenners( was, ja meist so ist), wird geprüft ob der zähler durch den nenner zu teilen geht. ist das nicht der fall wird halt der zähler so lange - 1 gerechnet bis es geht. ist also richtig.
was den euklidischen algorithmus betrifft: hierzu müsste eine dritte zahl eingegeben werden und das soll aber nicht der fall ein, zudem müssten evtl. mehrere eingaben erfolgen
-
Du könntest auch mit demjenigen der heute morgen das Problem mit der Menüeingabe hatte den logischen Operator der Abbruchbedingung tauschen, dann passts bei Euch beiden

(Er hatte nen || wo ein && hingehörte, bei Dir umgekehrt).
-
echt jetzt?! || ist doch aber logisch ODER, oder etwa nich?

-
was den euklidischen algorithmus betrifft: hierzu müsste eine dritte zahl eingegeben werden und das soll aber nicht der fall ein, zudem müssten evtl. mehrere eingaben erfolgen
Wo hast du denn den (sorry) Käse gelernt? Der Euklidische Algorithmus berechnet den ggT von genau zwei Zahlen - da brauchst du keine zusätzlichen Eingaben.
-
MW_ICEMAN schrieb:
echt jetzt?! || ist doch aber logisch ODER, oder etwa nich?

Ja, und die Schleifenbedingung gibt an, wann die Schleife fortgesetzt werden soll - in deinem Fall wenn 'temp' ODER 'temp2' ungleich 0 sind.
-
Ja, || ist logisches Oder.
Du sagtest nur dass er die Schleife verlässt wenn temp2 == 2 ist (was er nicht soll). Wenn temp2 == 2 und temp == 0 verlässt er aber durchaus die Schleife (den Wert von temp hattest Du nicht erwähnt). Das würde sich durch Abwandeln der Bedingung ändern.
-
lol ich habs.... thx!!!!!!!!!
else
{
const int temp1 = zaehler;do
{zaehler=zaehler-1;
cout<<"zaehler "<<zaehler<<endl<<endl;
temp=nenner%zaehler;
cout<<"temp "<<temp<<endl<<endl;
temp2=temp1%zaehler;
cout<<"temp2 "<<temp2<<endl<<endl;}
while (temp2 !=0 || temp !=0);nenner=nenner/zaehler;
zaehler=zaehler/zaehler;zaehler=nenner-zaehler;
}
hat geklappt

-
Etwas ordenticher sähe das dann so aus:
void kurz (int &zaehler, int &nenner) { for(int i=0; i<min(zaehler, nenner) && abs(zaehler) > 1 && abs(nenner) > 1; ++i) { if(zaehler % i == 0 && nenner % i == 0) { zaehler /= i; nenner /= i; } }Aber wie schon erwähnt ist das nicht gerade effizient.
Jockel
-
Natürlich umgekehrt:
void kurz (int &zaehler, int &nenner) { for(int i=min(zaehler, nenner); i>1 && abs(zaehler) > 1 && abs(nenner) > 1; --i) { if(zaehler % i == 0 && nenner % i == 0) { zaehler /= i; nenner /= i; } }
-
ja klar,..... schon. aber wa ist, wenn beim ersten kürzen nicht komplett gekürzt wurde. Bsp: 'n bissl übertrieben: Wie kürzt man 68424/846026 ? Wahrscheinlich mit 2, aber es geht bestimmt auch anders... verstehst?

-
MW_ICEMAN schrieb:
ja klar,..... schon. aber wa ist, wenn beim ersten kürzen nicht komplett gekürzt wurde. Bsp: 'n bissl übertrieben: Wie kürzt man 68424/846026 ? Wahrscheinlich mit 2, aber es geht bestimmt auch anders... verstehst?

Klar kannst du jetzt anfangen, von 68424 an durchzutesten, bis du den ersten gemeinsamen Teiler gefunden hast, aber such dir vorher etwas, womit du die Wartezeit verbringen kannst
(oder schau dir den Euklid doch mal genauer an :D)