Skip to content
xenforo

Kurseinheit 3 - größter gemeinsamer Teiler

Content

KE 3 - größter gemeinsamer Teiler

Hallo,

in KE 3 soll man eine Übungsaufgabe zum ggt (Euklid) erstellen.
Die Lösung ist folgende:\

[FONT=Courier]
[FONT=Courier]public int gcd(int a, int b) // wir gehen davon aus,
[FONT=Courier]{ // dass a, b > 0
[FONT=Courier]int m = a; //Schritt 1: setze m=a, und n=b
[FONT=Courier]int n= b;
[FONT=Courier]int r; // Hilfsvariable
[FONT=Courier]do {
[FONT=Courier]if (m < n) // Schritt 2: falls m < n
[FONT=Courier]{
[FONT=Courier]r = m; // vertausche m und n
[FONT=Courier]m = n;
[FONT=Courier]n = r;
[FONT=Courier]}
[FONT=Courier]r = m - n; // Schritt 3: berechne r
[FONT=Courier]m = n; // Schritt 4: setze m und n
[FONT=Courier]n = r;
[FONT=Courier]} while ( r != 0); // Schritt 5: weiter mit Schritt 2
[FONT=Courier]return m; // beende das Verfahren, m liefert
[FONT=Courier]} // den ggt von a und b\


Ich Frage mich nur, ob die Hilfsvariablen und das vertauschen überhaupt notwendig sind?
Reicht nachstehender Code nicht auch aus?

while ( a != b )
{
if ( a > b )
{
a -= b;
}
else if ( a < b )
{
b -= a;
}
}
return a;

Comments

deinSchatten wrote:


Reicht nachstehender Code nicht auch aus?

Die Musterlösung habe ich mir jetzt noch gar nicht angesehen, aber bei deinem Beispiel kann man für a eine positive und für b eine negative Zahl eingeben und dann ist man in einer Endlosschleife, oder?

[FONT=F23][FONT=F23]bei der Musterlösung schreiben die ja auch das man davon ausgeht das nur positive eingegeben werden

deinSchatten wrote:

[FONT=F23][FONT=F23]bei der Musterlösung schreiben die ja auch das man davon ausgeht das nur positive eingegeben werden ;)\

Ach so! Dann sorry für den vorschnellen Schuß.

Hat keiner eine Anwort?

deinSchatten wrote:

Hat keiner eine Anwort?

Jedenfalls keine negative! Sieht für mich logisch gut aus; hab's gerade eingegeben und mit einem Haufen von Zahlenpaaren geprüft; kam immer das richtige Ergebnis raus.

Sehr gutes Beispiel, wie kann man Code sparen.

Bei mir auch alle Ergebnisse sind gleich.

Hehe dann hab ich das ja doch richtig verstanden ;)
warum einfach wenn es doch auch kompliziert geht

Ja dein Code ist auf jedenfall kürzer, was ich nur anmerken möchte ist, bei der Musterlösung werden schon mit Absicht die variablen a und b durch m und n ersetzt, weil man sonst nach dem alg. nicht mehr auf diese zugreifen kann, einfaches beispiel wäre zb, wenn man vor dem return direkt eine ausgabe machen möchte a la "Der ggT von 'a' und 'b' ist 'm'." wird es schwierig, weil du direkt a und b veränderst, soll keine Kritik sein nur eine kleine Anmerkung... Das kann einem nämlich später, wenn es nicht mehr um primitive Typen sondern um Objekte geht, probleme bereiten, wenn man das ursprungsobjekt verändert.
ggf noch schneller ginger:


int m=a;
int n=b;
int r;
while(n!=0) {
r = m%n;
m = n;
n = r;
}
return m;\

das ist der "neue" Euklid

Gut! Die Anmerkung ist rechtzeitig.
Habe gerade mit Objekte probiert.

Ja bei Objekten gibt es ein paar besonderheiten dabei... weil m = a, nicht so ganz das macht was man erst denkt, weil wenn man nun etwas in m ändert ändert sich dies auch bei a... Dafür gibt es die methode clone(), da durch wird sicher gestellt, dass änderungen an m nicht auf a zurück wirken. Ich versuch es mal einem Beispiel zu verdeutlichen.
Ich habe eine Klasse Test geschrieben, die ein Attribut (String str) besitzt und in der auch 2 Objekte von Test erzeugt werden t1 und t2. Habe hoffentlich alles ausreichend Kommentiert und der unterschied zwischen = und clone() wird deutlich.
Der Code kann so in BlueJ in eine Klasse Test eingefügt werden und über die Methode void main(..) aufgerufen werden.
[CODE]
/**
* Die Klasse <b>Test</b> soll den Unterschied zwischen = und clone() verdeutlich.<hr />
* Kurze Erklärung zu sachen die Überlesen werden sollten:<br />
* <i>implements Cloneable</i>, ist nötig, damit man Objekte vom Typ Test clonen kann.<br />
* <i>throws CloneNotSupportedException</i> bei manchen Methoden<br />
* habe ich eingefügt um die Lesbarkeit zu erhöhen und keine try-catch- Blöcke einfügen muss.
* @author Martin
* @version 0.1
*
*/
public class Test implements Cloneable{
private String str;

/**
* Erzeugt ein Test Objekt mit einem bestimmten String.
* @param str
*/
public Test(String str) {
this.str = str;
}

/**
* Ändert den aktuellen String auf den String neu
* @param neu
*/
public void setStr(String neu) {
this.str = neu;
}

/**
* Main methode, kann ohne Objekt aufgerufen werden.
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Test t1 = new Test("a"); // Objekt von Test erzeugen.
Test t2; // t2 initialisieren.

// Gleichsetzen:
t2 = t1;
System.out.println(t1 + " " + t2); // Ausgabe: a a

// t1 wird geändert auf "b":
t1.setStr("b");
System.out.println(t1 + " " + t2); // Ausgabe: b b

// t2 wird geändert auf "c":
t2.setStr("c");
System.out.println(t1 + " " + t2); // Ausgabe: c c

// changeDirect aufruf (a=b):
changeDirect(t1);
System.out.println(t1 + " " + t2); // Ausgabe: d d

// changeIndirect aufruf (a=b):
changeIndirect(t1);
System.out.println(t1 + " " + t2); // Ausgabe: e e

// changeClone aufruf (a=b):
changeClone(t1);
System.out.println(t1 + " " + t2); // Ausgabe: e e

System.out.println(); // Leer Zeile


t1 = new Test("a"); // t1 auf Ausgang zurücksetzen.
t2 = null; // t2 auf Ausgang zurücksetzen.

// Clone():
t2 = (Test) t1.clone();
System.out.println(t1 + " " + t2); // Ausgabe: a a

// t1 wird geändert auf "b":
t1.setStr("b");
System.out.println(t1 + " " + t2); // Ausgabe: b a

// t2 wird geändert auf "c":
t2.setStr("c");
System.out.println(t1 + " " + t2); // Ausgabe: b c

// changeDirect aufruf (b = a.clone()):
changeDirect(t1);
System.out.println(t1 + " " + t2); // Ausgabe: d c

// changeIndirect aufruf (b = a.clone()):
changeIndirect(t1);
System.out.println(t1 + " " + t2); // Ausgabe: e c

// changeClone aufruf (b = a.clone()):
changeClone(t1);
System.out.println(t1 + " " + t2); // Ausgabe: e c
}

/**
* Ändert den String von t direkt.
* @param t
*/
public static void changeDirect(Test t) {
t.setStr("d");
}

/**
* Ändert den String von t indirekt über t3 (t3 = t).
* @param t
*/
public static void changeIndirect(Test t) {
Test t3 = t;
t3.setStr("e");
}

/**
* Ändert den String von t an einem Clone t3 (t3 = t.clone())
* @param t
* @throws CloneNotSupportedException
*/
public static void changeClone(Test t) throws CloneNotSupportedException {
Test t3 = (Test)t.clone();
t3.setStr("f");
}

@Override
public String toString() {
return str;
}

}
[/CODE]

Ist schon richtig professionell :)

So viel kommentare braucht man, glaube ich, nicht.
Code ist ganz klar.
Vielen Dank für tiefere Einführung in OOP.

Einige Kommentare grade die mit:
/**
*
**/
dienen eher der Javadoc, wenn man in BlueJ auf "Tools->Project Documentation" klickt (Strg+J) wird ne schöne API dazu erzeugt