Multiplikation mit rekursivem Aufruf

Wang

Bekanntes Mitglied
Hallo,

ich habe diesen Code hier in Java-Code übersetzt, erhalte bei der Ausführung des Programms aber die Fehlermeldung "Exception in thread "main" java.lang.StackOverflowError
at Mult.mult(Mult.java:19)
..."

Weiß jemand, wo der Fehler liegt?

Gruß
Wang


Code:
function int mult(int a, int b){
	if(a == 0) {
		return 0;
	}
	else {
		a = a - 1;
		int c = mult(a, b);
		int d = b + c;
		return d;
	}
}

Java:
// Datei: Mult.java

public class Mult
{
	private int a;
	private int b;
	private int c;
	private int d;
	
	public int mult (int a, int b)
	{
		if (a == 0)
		{
			return 0;
		}
		else
		{
			this.a = a - 1;
			this.c = mult(a, b);
			this.d = b + c;
			return d;
		}
	}
	
	public void print()
	{
		System.out.println ("Das Produkt lautet: " + d);
	}
	
	public static void main (String[] args)
	{
		Mult test = new Mult();
		test.mult(2,3);
		test.print();
	}
}
 

preachie

Aktives Mitglied
[JAVA=18] this.a = a - 1;
[/code]

Du ziehst von dem lokalen a 1 ab und weist das Ergebnis der Klassenvariable a zu.
Übergeben tust Du dann aber wiederum die lokale Variable a die weiterhin unverändert ist, so dass die Bedingung a == 0 nie erfüllt ist.
Daher fliegt Dir irgendwann der Stack um die Ohren wenn ein paar Hundert/Tausend/Millionen/Milliarden Mal die mult() Methode aufgerufen wurde ;)
 

Marco13

Top Contributor
Zwischen dem Parameter 'a' und 'this.a' ist ein Unterschied. Manchmal ist es einfacher, als man vielleicht denkt.
(Meistens aber nicht, also nicht zu optimistisch werden :D )
Java:
public class Mult
{
    public int mult (int a, int b)
    {
        if (a == 0)
        {
            return 0;
        }
        else
        {
            a = a - 1;
            int c = mult(a, b);
            int d = b + c;
            return d;
        }
    }

    public static void main (String[] args)
    {
        Mult test = new Mult();
        System.out.println ("Das Produkt lautet: " + test.mult(2,3));
    }
}
 

Haave

Top Contributor
StackOverflowError bedeutet, dass die Berechnung länger dauert, als Speicher dafür im Computer vorhanden ist. Das Code braucht also aus irgendeinem Grund endlos lange.
Hast du überprüft, ob der Ausgangscode (also dein gefundener Code) überhaupt einwandfrei funktioniert? Ich bin nicht so der Pro bei Rekursion, aber mir kommt der rekursive Aufruf in Zusammenhang mit der Zuweisung komisch vor und dass d beim Abarbeiten des Stacks mehrmals zurückgegeben werden müsste. Es sollte aber nochmal jemand anders drüberschauen, der mehr Ahnung davon hat als ich.

EDIT:
Okay, ist also schon passiert ^^;

Sorry für den verzapften Mist… :(
 
Zuletzt bearbeitet:

Andi_CH

Top Contributor
Java:
public class mult {

	private static int multiply(int a, int b){
		if(a == 1) {
			return b;
		} else {
			return b + multiply(--a, b);
		}
	}
	public static void main(String[] args) {
		System.out.println(multiply(3, 5));

	}
}
> 15

Funktioniert allerdings nur für positive Zahlen
 

Andi_CH

Top Contributor
StackOverflowError bedeutet, dass die Berechnung länger dauert, als Speicher dafür im Computer vorhanden ist. Das Code braucht also aus irgendeinem Grund endlos lange.
...
EDIT:
Okay, ist also schon passiert ^^;

Sorry für den verzapften Mist… :(

Ich relativiere den "Mist" mal ;-)

"lange" hat nicht zwingend mit "Speicher" zu tun? ;-)
Java:
while (true) {
	System.out.println("blabla");	
}
Wird beliebig lange laufen aber keinen Stackoverflow produzieren

Stackoverflow hat damit zu tun, dass der Prozess Stack verbraucht und nicht mehr frei gibt - z.B. bei einer Rekursion, die nie abbricht. Für den Rücksprung wichtige Daten und lokale Variablen, im Beispiel unten das j, werden bei jedem Prozeduraufruf auf den Stack gelegt und erst beim Rücksprung freigegeben.

unendlicheRekursion:

Beachte! -- wird erst ausgeführt nachdem der Wert an unendlicheRekursion(i--); übergeben wurde
Java:
	private static void unendlicheRekursion(int i) {
		int j = i; // nur zur Demo, damit der Stack auch wächst ;-)
		System.out.println(j);
		if (j<=0)
			System.out.println("Ende der Rekursion"); // wird nie erreicht!
		else
			unendlicheRekursion(j--); // Bewirkt nichts mehr
	} // Platz für j und Rücksprungframe wird freigegeben - diese Zeile wird aber nie erreicht
Aufruf: unendlicheRekursion(3)
Ausgabe:
3
3
3
........ irgendwann dann Stack overflow

Die korrekte Variante:
Java:
	private static void endlicheRekursion(int i) {
		int j = i; // nur zur Demo, damit der Stack auch wächst ;-)
		System.out.println(j);
		if (j<=0)
			System.out.println("Ende der Rekursion");
		else
			endlicheRekursion(--j); // Korrekte Variante
	} // Platz für j und Rücksprungframe wird freigegeben
Ausgabe:
3
2
1
0
Ende der Rekursion

Wenn die Methode etwas mehr als nur einen int alloziert und der Aufruf mit MAXINT erfolgt, kann es allerdings auch zu einem Stack overflow kommen...
 
Zuletzt bearbeitet:

Andi_CH

Top Contributor
Ich perönlich finde die ?: Notation hässlicher - na ja zumindest unleserlicher als die andere.
Aber jeder nach seinem Geschmack.
 

Landei

Top Contributor
Java:
public static int mul(int a, int b){
   return a==0 ? 0 : mul(a >> 1, b+b) + ((a&1) > 0 ? b : 0); 
}
 

Andi_CH

Top Contributor
Da war doch mal was mit der unleserlichsten Zeile C Code .....

Im aktuellen Projekt ist diese Art des if's tabu - die Wartbarkeit des Codes leide.
Ich habe keine Ahnung in wie weit sich der Javacomplier steuern lässt um optimierteren Code zu erzeugen, aber darum kümmere ich mich nie - wenn es optimert sein muss, setze ich halt C ein

Ist das ein relevanter Laufzeitunterschied ?

Java:
public static int mul(int a, int b){
   return a==0 ? 0 : mul(a >> 1, b+b) + ((a&1) > 0 ? b : 0); 
}

Java:
public static int mul(int a, int b){
   int retVal = 0;
   if(...)
      ...;
   else
      ...;
   return retVal; 
}
 

Landei

Top Contributor
Nein, ich denke da kommt die gleiche Performance heraus. Allerdings ist die Frage, ob die Operationen >> und & bei der Aufgabe "zugelassen" sind (das & könnte man noch ersetzen, das >> nicht so richtig). Der Algorithmus ist übrigens die Russische Bauernmultiplikation
 

Marco13

Top Contributor
Hier nochmal mit der Multiplikationsformel von Kasimir Kostonjenko
Java:
public static int mul(int a, int b)
{
   if (a==1) return b;
   if (b==1) return a;
   return mul(1, a*b);
}
 

Andi_CH

Top Contributor
Könnte sein, wenn man davon ausgehen muss dass sehr oft Multiplikationen mit 1 vorkommen, bringen die ersten zwei Zeilen einen Gewinn, aber spätestens die Dritte kann direkt als
Java:
return a*b
geschrieben werden

gibt es auch ein [JOKE][/JOKE] Tag ? :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L Switch-Case Multiplikation wird nicht ausgegeben Java Basics - Anfänger-Themen 1
padde479 Array Multiplikation der ersten n Zahlen Java Basics - Anfänger-Themen 7
S Multiplikation von zwei Labels Java Basics - Anfänger-Themen 7
F Matrix Multiplikation Java Basics - Anfänger-Themen 3
G Java Bruchrechner Addition, Multiplikation... Java Basics - Anfänger-Themen 12
Z Matrix Klasse mit Mehrdimensionalen Array (Addition, Multiplikation, to String) Java Basics - Anfänger-Themen 57
O Erstes Programm: Matrizen Multiplikation Java Basics - Anfänger-Themen 10
H Variablen Multiplikation einer inkrementierten Variablen Java Basics - Anfänger-Themen 5
D Methoden Matrix Multiplikation Java Basics - Anfänger-Themen 27
J Funktionsaufrufe Multiplikation von Arrays Java Basics - Anfänger-Themen 3
Joker4632 Klassen BigDecimal Multiplikation liefert nicht erwarteten Wert Java Basics - Anfänger-Themen 6
TomatenBrot447 Adapter für eine optimierte Multiplikation Java Basics - Anfänger-Themen 5
U Ist diese Methode zur Matrix Vektor Multiplikation korrekt ? Java Basics - Anfänger-Themen 5
K Multiplikation zweier Matrizen Java Basics - Anfänger-Themen 23
P Variablen Negatives Ergebnis bei Multiplikation von großen Zahlen Java Basics - Anfänger-Themen 2
R Matrix-Vektor-Multiplikation Java Basics - Anfänger-Themen 13
K Seltsames Ergebnis in Netbeans bei einfacher Multiplikation Java Basics - Anfänger-Themen 5
T Operatoren Multiplikation nur mit Addition, Subtraktion und Vergleich Java Basics - Anfänger-Themen 29
S Multiplikation durch Addition, Subtraktion und Vergleich von Zahlen Java Basics - Anfänger-Themen 14
V Vor jeder Multiplikation den linken Multiplikator abrunden Java Basics - Anfänger-Themen 4
M Matrix Matrix Multiplikation Java Basics - Anfänger-Themen 6
S Multiplikation von großen Zahlen, ohne BigInt uä Java Basics - Anfänger-Themen 7
F.S.WhiTeY Multiplikation nach der Schulmethode Java Basics - Anfänger-Themen 6
K Matrizen Multiplikation Java Basics - Anfänger-Themen 3
B Multiplikation bei Generics Java Basics - Anfänger-Themen 9
G Multiplikation falsches Ergebnis Java Basics - Anfänger-Themen 5
K double Multiplikation Java Basics - Anfänger-Themen 2
K einfache Multiplikation Java Basics - Anfänger-Themen 6
2 Variablenüberlauf bei Addition, Multiplikation Java Basics - Anfänger-Themen 2
O Überlauf durch Multiplikation Java Basics - Anfänger-Themen 7
S Problem mit einem rekursivem FloodFill Algorithmus Java Basics - Anfänger-Themen 62
O Hilfestellellung bei Rekursivem Löschen Java Basics - Anfänger-Themen 11
I Listendublette bei rekursivem Komponentenaufruf Java Basics - Anfänger-Themen 4
C Deklaration einer Variablen in einem rekursivem Aufruf Java Basics - Anfänger-Themen 5
T Aufruf der Methode einer Oberklasse, wenn sie in der Unterklasse überschrieben ist. Polymorphie. Java Basics - Anfänger-Themen 2
M Konstruktor-Aufruf im Konstruktor, aber nicht am Anfang? Java Basics - Anfänger-Themen 4
P Array-Objekte-Aufruf Java Basics - Anfänger-Themen 22
Agent4nobody Programmstart durch aufruf des interpreters funktioniert nicht Java Basics - Anfänger-Themen 14
G Main Methode wird beim ersten Aufruf nicht richtig ausgeführt Java Basics - Anfänger-Themen 1
K Erste Schritte Stream-Aufruf vereinfachen Java Basics - Anfänger-Themen 3
sashady ursprüngliche Array-Werte bei erneutem Aufruf? Java Basics - Anfänger-Themen 7
M Aufruf von statischen Methoden einer anderen Klasse Java Basics - Anfänger-Themen 15
Y Aufruf von Methode nicht möglich. Java Basics - Anfänger-Themen 2
D Aufruf von mehreren Activities bringt die app zum Absturz Java Basics - Anfänger-Themen 5
L Methoden Wie Löse ich ext Methoden Aufruf Fehler? Java Basics - Anfänger-Themen 3
X Methode bei mehrfachen Aufruf kein Effekt Java Basics - Anfänger-Themen 3
H Aufruf von Methoden durch Methoden Java Basics - Anfänger-Themen 3
B EJB und Arquillian - bekomme Nullpointer Exception beim Aufruf der EJB Klasse Java Basics - Anfänger-Themen 40
O Verwirrt beim Java Collection Framework aufruf! Java Basics - Anfänger-Themen 9
T Konsolenscanner startet nicht durch Aufruf von Actionlistener Java Basics - Anfänger-Themen 4
B OOP While Schleife läuft Endlos durch externen aufruf Java Basics - Anfänger-Themen 2
E Vererbung super-Methoden Aufruf Java Basics - Anfänger-Themen 3
D Interface Wieso Aufruf aller Methoden eines Interfaces? Java Basics - Anfänger-Themen 11
R Methoden NPE beim Aufruf einer Methode einer anderen Klasse Java Basics - Anfänger-Themen 4
J Aufruf einer Methode über einen String Java Basics - Anfänger-Themen 11
A Aufruf von Konstruktor , obwohl 2 Parameter weggelassen werden Java Basics - Anfänger-Themen 7
A Aufruf von Konstruktor , obwohl 2 Parameter weggelassen werden Java Basics - Anfänger-Themen 0
H Rekursiver Aufruf Java Basics - Anfänger-Themen 8
E Daten dem Super Aufruf übergeben Java Basics - Anfänger-Themen 3
D Interface Frame doppelt durch Aufruf der GUI Klasse Java Basics - Anfänger-Themen 1
Henri Aufruf von getX() und getY() aus der Super klasse Objekt() Java Basics - Anfänger-Themen 3
E Aufruf auf Objekt mit übergebenem Wert? Java Basics - Anfänger-Themen 7
D Aufruf einer statischen Variable Java Basics - Anfänger-Themen 1
D Aufruf einer Methode einer anderen Klasse Java Basics - Anfänger-Themen 39
T static String Variable wird nur beim ersten aufruf durch eine Funktion geändert. Java Basics - Anfänger-Themen 16
C Erste Schritte Fehler beim *.class Aufruf über cmd.exe Java Basics - Anfänger-Themen 9
M Speichern von Objekten - Verfügbarkeit bei erneutem Aufruf Java Basics - Anfänger-Themen 3
S PHP Aufruf mit mehreren Variablen Java Basics - Anfänger-Themen 2
P Aufruf Methode anderer Klasse Java Basics - Anfänger-Themen 5
J Klassen Reihenfolge beim Aufruf von Klassen Java Basics - Anfänger-Themen 1
V Problem Aufruf einer Methode in einer Methode Java Basics - Anfänger-Themen 1
O Frage zum Aufruf überladener Methoden Java Basics - Anfänger-Themen 4
G funktions Aufruf aus GUI Java Basics - Anfänger-Themen 9
A Fehlermeldung beim aufruf der main Methode Java Basics - Anfänger-Themen 17
I Rückgabe und Aufruf einer Methode innerhalb einer anderen Methode Java Basics - Anfänger-Themen 5
W Zeitversetzter Aufruf der Methoden Java Basics - Anfänger-Themen 6
M Unbekannte Nummer bei Aufruf der toString Methode Java Basics - Anfänger-Themen 3
D Methode mit mehren Rekursiven aufrufen in Methode mit einem Rekursiven Aufruf umwandeln! Java Basics - Anfänger-Themen 1
F signiertes Applet fkt. nicht bei lokalem Aufruf Java Basics - Anfänger-Themen 2
A externer repaint Aufruf Java Basics - Anfänger-Themen 9
H Aufruf einer Instanzmethode funktionert nicht. Java Basics - Anfänger-Themen 6
A Konstruktor Aufruf Java Basics - Anfänger-Themen 4
Pentalon Ein Aufruf den ich nicht verstehe Java Basics - Anfänger-Themen 11
D dynamischer Aufruf Java Basics - Anfänger-Themen 2
N Aufruf der Methode Java Basics - Anfänger-Themen 16
L Next()-Aufruf zweimal innerhalb einer While-Schleife bei ListIterator Java Basics - Anfänger-Themen 10
S Aufruf Einer Methode aus einer anderen Klasse - Static Fehler Java Basics - Anfänger-Themen 4
A Aufruf der paint() Methode Java Basics - Anfänger-Themen 3
K Problem beim Array aufruf Java Basics - Anfänger-Themen 4
P URL für Lokalen Aufruf Java Basics - Anfänger-Themen 5
C OOP Aufruf von Methoden höherer Sichtbarkeit Java Basics - Anfänger-Themen 10
T Client-Fenster bei Aufruf unvollständig Java Basics - Anfänger-Themen 12
S Überladener Konstruktor und aufruf aus eigener Klasse Java Basics - Anfänger-Themen 2
A Aufruf von Konstruktor aus Basisklasse Java Basics - Anfänger-Themen 7
O OOP super aufruf 2 objekte? Java Basics - Anfänger-Themen 3
D Array Methoden Aufruf. Java Basics - Anfänger-Themen 14
L Klassen Aufruf einer ueberschreibbaren Methode im Konstruktor Java Basics - Anfänger-Themen 4
M OOP Aufruf vieler Getter Methoden abkürzen? Java Basics - Anfänger-Themen 7
Q Aufruf einer Klasse in einem Package Java Basics - Anfänger-Themen 7
C Aufruf funktioniert nicht Java Basics - Anfänger-Themen 10

Ähnliche Java Themen

Neue Themen


Oben