# Euklid Klasse mit Methoden zur Berechnung des ggT



## serendipity (29. Okt 2007)

Hallo alle zusammen!

Ich bin ein wenig (schwer untertrieben) am verzweifeln: als Java-Neuling soll ich studiumsbedingt folgendes machen:
1.) eine Klasse Euklid programmieren, die eine Methode zur Berechnung des größten gemeinsamen Teilers enthalten soll (Diese Methode soll mit Eingaben aus den ganzen Zahlen korrekt funktionieren, d.h. auch mit Zahlen kleiner gleich Null, Hinweise, die mir gegeben sind: ggT(0, n) = ggT(n, 0) = |n| und ggT(0, 0) = 1)
Ausgangspunkt soll folgendes Skript sein:


```
public class GGT2 { /* Klassenname geaendert */
    public static int 
        euklidModern(int x, int y) { /* Methodenname geaendert */
	int r;
	while ( y != 0) { 
	    r = x % y; 
	    x = y; 
	    y = r;
	}
	return x;    // Wertuebergabe
    }    
    public static void main( String[] args){// Anfang (Testumgebung)
        int a = Integer.parseInt(args[0]);
        int b = Integer.parseInt(args[1]);
	if ( a <= 0 || b <= 0) 
	    System.out.println("negative Parameter nicht erlaubt!");
	/* richtig muesste es lauten: 
	   "nur positive Parameter erlaubt!" */
	else 
	    System.out.println(euklidModern(a, b));
    } // Ende (Testumgebung)
}
```

2.) die Klasse Euklid soll dann um eine Methode kgV ergänzt werden, die, mit der oben angegebenen Berechnungsvorschrift, das kleinste gemeinsame Vielfache zweier ganzer Zahlen berechnet und zurückliefert

Die Aufgabe geht noch weiter, aber ich muss ja dieses hier erstmal verstehen/realisieren. Generell ist mir die Funktionsweise des Skripts verständlich, nur leider hatte ich vorher noch nie mit Java zu tun, folglich auch keinerlei Erfahrung, wie man soetwas umsetzt... Wahrscheinlich ist das für die Geübten unter euch recht simpel?!

Ich wäre euch äußerst dankbar, wenn ich einige wertvolle Tipps erhalten könnte, bitte aber leicht verständlich und nicht zu kompliziert 

Vielen Dank schonmal,
lg, Sara[/quote]


----------



## DocRandom (29. Okt 2007)

..tjo, bei mir ist die Schule schon etwas länger her, genauer gesagt so um die 30 Jahre, daher mal meine Frage:
Wie lautet denn die Formel für das kleinste gemeinsame Vielfache?

lg
DocRandom


----------



## nebulo (29. Okt 2007)

Ich weiß ja nicht ob ihr nun den kgv auf der grünen Wiese programmieren sollt oder unter der Annahme, dass ggt schon zur Verfügung steht. Denn dann ist es ganz einfach:

kgv(x,y) = (x*y)/ggt(x,y)

Ggf. musst du halt einen Beweis schreiben, dass dieser Zusammenhang korrekt ist. Das Verfahren wie man den kgv berechnet wirst du ja kennen.

Gruß nebulo

EDIT: Hatte das mit dem ggt für negative Zahlen ganz überlesen. Ich denke es sollte funktioieren, wenn du einfach absolut Werte übergibst. also ggt(|x|,|y|) aber ich habe jetzt weder genauer nachgedacht noch an Beispielen verifiziert gewescheigeden bewiesen.


----------



## Joker (29. Okt 2007)

hier ist der Algorithmus beschrieben:

http://de.wikipedia.org/wiki/Erweiterter_euklidischer_Algorithmus

(denke einfach mal das der erweiterte gesucht ist). Irgendwo hab ich sowas noch liegen, ich schau mal ob ichs auch finde 

wenns doch der normale ist:
http://de.wikipedia.org/wiki/Euklidischer_Algorithmus

auf den Wikipedia Seiten gibts auch einige weiterführende Links mit schönen interaktiven Schritt für Schritt Beispielen.


----------



## DocRandom (29. Okt 2007)

nebulo, Deine Antwort ist korrekt, jedoch wollte ich eigentlich den/die serendipity zum Nachdenken bringen!
Immerhin ist es ja auch Ihre/Seine HA ;

lg
DocRandom


----------



## nebulo (29. Okt 2007)

Ich gebe dir an der Stelle natürlich Recht DocRandom! Ich hätte nicht ganz so schnell damit rausrücken sollen . Aber es gibt eigentlich immer noch Genügend über das Sie nachdenken sollte. Ich hoffe Sie tut das auch. Vorallem sollte Sie versuchen das Alles zu verstehen und vielleicht tatsächlich versuchen, die Korrektheit zu beweisen.


----------



## serendipity (29. Okt 2007)

ich danke euch schonmal fürs nachdenken & helfen (und glaubt mir, ich hab mir selbst schon den kopf zerbrochen!!)

ich hatte vergessen zu schreiben, dass ich die berechnung des kgv schon kenne (eben genau diese formel wie oben geschrieben) - da es in der aufgabe heißt: "ergänze die klasse euklid um eine methode kgv..." nehme ich an, dass wir voraussetzen dürfen, den ggT bereits zu kennen, folglich auch keinen beweis liefern müssen.

mein größtes problem liegt einfach darin, dass ich wie gesagt keine erfahrung im umsetzen dieser dinge in java-skript habe... soll heißen: wie (und was) füge ich genau an das bestehende skript an, damit er mir nach der Berechnung des ggT auch den kgV ausgibt?

und zu der frage mit den negativen zahlen:  muss ich einfach nur die beiden anfangsvariablen als beträge schreiben (also mit "|y|") oder müsste ich dies auch in den anweisungen der while-schleife berücksichtigen?

lg
serendipity


----------



## nebulo (29. Okt 2007)

Also sehr schwer dürfte es nicht mehr sein von dem Zusammenhang kgv(x,y) = (x*y)/ggt(x,y) auf die Methode zu kommen.

Eine entsprechende Methode kgv hat folgende Signatur:

public (static )int kgv(int x, int y);

den Rest solltest du schon selbst hinbekommen.

Das mit den Beträgen würde ich so machen, dass in der Methode euklidModern(...) einfach die Absolut-Werte (java.lang.Math.abs(...)) zum weiterrechnen nimmst anstatt der übergebenen möglicherweise negativen Zahlen. 

Gruß nebulo


----------



## serendipity (29. Okt 2007)

nicht böse sein, ich mach sowas wirklich zum ersten mal...  :cry: 

habe jetzt folgendes gebastelt:


```
public class Euklid1 { 
    public static int
        ggt(int java.lang.Math.abs(x), int java.lang.Math.abs(y)) { 
   int r;
   while ( y != 0) {
       r = x % y;
       x = y;
       y = r;
   }
   return x;    // Wertuebergabe
    }   
    public static void main( String[] args){// Anfang (Testumgebung)
        int a = Integer.parseInt(args[0]);
        int b = Integer.parseInt(args[1]);
        System.out.println(ggt(a, b));

    }

    public static int
        kgv(int java.lang.Math.abs(x), int java.lang.Math.abs(y)) { 
	return( x*y/ggt(x,y) );
    } 
}
```

natürlich findet der compiler fehler: zum einen erwartet er bei "java.lang.Math.abs" nach java ein ")"  und zum anderen nach der vorletzten geschweiften klammer ein semikolon... warum??? is das vielleicht generell totaler quatsch, was ich da geschrieben habe?


----------



## DocRandom (29. Okt 2007)

Hallo serendipity!

Ich war so frei und habe Deine Klasse nachgebaut:

```
package serendipity;

public class Euklid {

	public static int gGT(int x, int y) {
		
		int r;
		while (y != 0) {
			r = x % y;
			x = y;
			y = r;
		}
		return x;
	}
	
	public static int kGV(int x, int y) {
		return (x * y)/gGT(x, y);
	}
}
```
..und noch die Main-Klasse dazu:

```
package serendipity;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		/* negative Parameter ignorieren */
		int a = java.lang.Math.abs(Integer.parseInt(args[0]));
        int b = java.lang.Math.abs(Integer.parseInt(args[1]));
        /* gibts was zu berechnen ? */
        if((a == 0)||(b == 0)) {
        	// nein
        	System.out.println("Bitte Sinnvolle Parameter anwenden!");
        } else {
        	// ja
        	System.out.println("Der größte gemeinsame Teiler von "+ a +" und "+ b + " lautet: "+ Euklid.gGT(a,b));
        	System.out.println("Das kleinste gemeinsame Vielfache von "+ a +" und "+ b + " lautet: "+ Euklid.kGV(a,b));
        }
	}
}
```
..und bei mir kommt keine Fehlermeldung 

lg
DocRandom


----------



## nebulo (30. Okt 2007)

Ja so siehts gut aus @DocRandom. Ich würde lediglich das mit dem abs  noch in der Methode ggt verstecken.

Gruß nebulo


----------



## DocRandom (30. Okt 2007)

..und warum gerade dort?

lg
DocRandom


----------



## nebulo (30. Okt 2007)

Stichwort - Information Hiding (http://en.wikipedia.org/wiki/Information_hiding der Englische Artikel ist etwas besser als der Deutsche aber auch nicht perfekt)! Du erhälst so eine Methode um den GGT zu berechnen die auch für negative Werte funktioniert also allgemeiner ist. Denjenigen, der eine Methode benutzt braucht es nicht zu interessieren bzw. interessiert es nicht, wie intern eine Methode funktioniert. Und in diesem Fall weiß er ggf. gar nicht, dass man einfach absolut-Werte bilden muss um den GGT von negativen Zahlen zu berrechnen. Er muss also lediglich wissen, dass die Methode auch für negative Werte dass richtige Ergebniss liefert und kann in seinem Programm auf die Methoden zurückgreifen ohne Ahnung von mathematischen Details zu haben.

Ebenfalls würde ich folgendes in die GGT-Methode packen:



> ```
> if((a == 0)||(b == 0)) {
> // nein
> System.out.println("Bitte Sinnvolle Parameter anwenden!");
> ...



und eine Exception werfen statt den Text an dieser Stelle auszugeben.


----------



## fehlerfinder (30. Okt 2007)

serendipity hat gesagt.:
			
		

> ```
> public class Euklid1
> {
> public static int ggt(int java.lang.Math.abs(x), int java.lang.Math.abs(y))
> ...



Um mal konkret auf deine Frage zu antworten:
In der Parameterliste der Methoden-Definition darf (man möge mich ggf. verbessern) kein Funktionsaufruf stehen. Also einfach

```
public class Euklid1
{ 
    public static int ggt(int x, int y)
    {
        int local_x = java.lang.Math.abs(x);
        int local_y = java.lang.Math.abs(y);
    [...]
    }
}
```
 (oder sowas in der Art). Das mit dem Semikolon erübrigt sich dann vermutlich von alleine.

Und nur für's Protokoll


			
				serendipity hat gesagt.:
			
		

> keine erfahrung im umsetzen dieser dinge in java-skript habe... soll heißen: wie (und was) füge ich genau an das bestehende skript


Java ist nicht JavaScript...


----------



## serendipity (30. Okt 2007)

jaaa... für euch ist das vermutlich alles einfach, aber ich guck mit sowas an und hab keine idee, was man wo hinsetzen darf und was nicht   

Jedenfalls: wenn ich die beiden codes von dir (@DocRandom) ausprobieren möchte, funktioniert da irgendwie was nicht: muss ich beide codes in getrennten dateien haben und diese auch getrennt übersetzen? wenn ich das tue, findet er beim übersetzen der Main-Klasse die class Euklid nicht... oder kann ich die beiden codes auch in einer datei verbinden?


----------



## nebulo (30. Okt 2007)

Hm, ich frage mich immer wieder auf welche Art und Weise in Schulen Jave gelehrt wird. Da wird einfach drauf losprogrammiert ohne jegliche grundlegenden Konzepte zu vermitteln. Das Ergebnis sieht man dann in Foren wie diesem hier. 

Also du könntest natürlich beide Klassen in eine Datei schreiben (da die Main-Klasse public sein muss, wäre die Euklid als innerclass zu realisieren). Allerdings tut man das nicht. Du willst ja vielleicht später die Klasse zur Berechnung des KGV/GGT in einem anderen Programm wiederverwenden.

Am Besten geht du folgendermaßen vor:

1. Lege einen Ordner serendipity an
2. Lege 2 Dateien Main.java und Euklid.java an
3. Kopiere den Code (siehe unten) in die entsprechende Datei
4. Übersetze den Code mit 'javac serendipity/Main.java'
5. Führe das Programm mit 'java serendipity/Main arg1 arg2' aus

Übrigens sollte der Fall, dass keine oder nur ein Argument übergeben werden abgefangen werden und eine Meldung ausgegeben werden die die Verwendung des Programms erklärt.

Code:

Euklid.java


```
package serendipity;

public class Euklid {

   public static int gGT(int x, int y) {
      //Use absolute values to correctly compute negative values
      int a = java.lang.Math.abs(x);
      int b = java.lang.Math.abs(y);
      int r;
      while (b != 0) {
         r = a % b;
         a = b;
         b = r;
      }
      return a;
   }
   
   public static int kGV(int x, int y) {
        //Use absolute values to correctly compute negative values
      	int a = java.lang.Math.abs(x);
        int b = java.lang.Math.abs(y);
	return (a * b)/gGT(a, b);
   }
}
```

Main.java


```
package serendipity;

public class Main {

   /**
    * @param args
    */
   public static void main(String[] args) {
        /* gibts was zu berechnen ? */
	int a = Integer.parseInt(args[0]);
        int b = Integer.parseInt(args[1]);
        if((a == 0)||(b == 0)) {
           // nein
           System.out.println("Bitte Sinnvolle Parameter anwenden!");
        } else {
           // ja
           System.out.println("Der größte gemeinsame Teiler von "+ a +" und "+ b + " lautet: "+ Euklid.gGT(a,b));
           System.out.println("Das kleinste gemeinsame Vielfache von "+ a +" und "+ b + " lautet: "+ Euklid.kGV(a,b));
        }
   }
}
```


----------



## fehlerfinder (30. Okt 2007)

serendipity hat gesagt.:
			
		

> jaaa... für euch ist das vermutlich alles einfach, aber ich guck mit sowas an und hab keine idee, was man wo hinsetzen darf und was nicht


Auch nicht immer so. Aber oft hilft dann ausprobieren bzw. das, was neu oder unverständlich ist (z.B. bei dir "package"?), speziell nachzuschlagen.



			
				serendipity hat gesagt.:
			
		

> muss ich beide codes in getrennten dateien haben und diese auch getrennt übersetzen?


Das Geheimnist ist das "package". Beide Dateien - Euklid.java und Main.java - liegen im Verzeichnis "serendipity" (das ist absichtlich der package-Name ;-) ). Dann wird das Ganze aus dem Parent-Dir (man verzeihe den englischen Begriff) von serendipity aus übersetzt

```
javac serendipity/Main.java
```
und ebenso aufgerufen

```
java serendipity/Main
```


----------



## Gast (4. Nov 2007)

So ein Zufall, genau so ein Programm müssen wir auch schreiben in Info und diesen Quelltext haben wir so auch bekommen... Da bekommt man also Ruck Zuck die Lösung im Internet vorgesetzt... 
Allerdings sollte die Sache mit dem Absolutbetrag mit einer Fallunterscheidung umgesetzt werden. Und es soll auch mit Zahlen gleich 0 funktionieren...


----------



## nebulo (4. Nov 2007)

Was soll der GGT von (0,0) sein? Ich sehe keinen großen Sinn darin! Mit dem euklidischen Algorithmus jedenfall lässt er sich nicht berechnen. Man kann es also nur hart reinkodieren.


----------



## Gast (4. Nov 2007)

von 0,0 soll er 1 sein... Tja, ob es Sinn macht oder nicht, steht so in der Aufgabe.


----------



## nebulo (4. Nov 2007)

Ja wiegesagt musst dann hart reinkodieren:


```
if (x = 0 && y = 0) retun 1;
```


----------



## Gast (4. Nov 2007)

ja, hab ich ja schon gemacht. ich hab meine aufgabe selbst gemacht


----------



## serendipity (7. Nov 2007)

ich danke euch allen sehr - ich habs letztendlich hinbekommen! danke für die Unterstützung & hilfreichen Tipps!


----------



## Gast (27. Nov 2008)

Implementieren sie in er der Klasse sechs Methoden, die folgendermaßen aufgerufen werden:
a) int q = quersumme(i);
berechnet die Quersumme q des übergebenen Integers i.
b) int c = kgv (i,j);
berechnet das kgv c der übergebenen Integer i und j.
c) int f = fakultaet (i);
d) double m = min (x,y);
gibt das Minimum m der beiden Doubles x,y zurück.
e) int c = collatz (i);
gibt den Collatzwert c des Integers i zurück.
f) menue();
gibt Informationen über die Funktionalität des Programms aus.
Verwenden Sie zur Fehlerbehandlung in den Methoden RuntimeExceptions. Schreiben Sie in der Methode main ein Testprogramm, welches benutzergesteuert die Methode testet.

Wer kann mir helfen?


----------

