# Problem bei Fakultät mit "for"-Schleife



## Pattafix299 (13. Mai 2015)

Hey Leute, ich habe ein Problem bei der Berechnung der Fakultät mit einer for-Schleife. 
Die Aufgabe lautet: Schreiben Sie das Programm zur Berechnung der Fakultät mit der notierten “for-Schleife” anstelle der Rekursion.Lassen Sie darin 9!, 6!, 3!, 0! und 20! berechnen.
Ich habe versucht, eine eigene Lösung zu schreiben, aber er zeigt mir immer den gleichen Fehler. Kann mir einer helfen und sagen, wie man diesen Fehler behebt? In Zeile 14 wird der Fehler angezeigt, also irgendwas mit der Klammer ist falsch.
Vielen Dank.
Pattafix299

Hier das Programm:

```
import eip.*;


public class Fakultät
{
static int factorial(int n )
 {
for (int i=0; i < n; i++)
   {
    int erg = n * factorial (n - 1);
    Std.out.println(n + "! = " + n + "*" + (n-1) + "!");
    Std.out.println(erg);
   }
 }


public static void main( String[] args )
   {
Std.out.println("5! = " + factorial( 5 ) );
Std.out.println("12! = " + factorial( 12 ) );
   }
}
```


----------



## InfectedBytes (13. Mai 2015)

dein factorial methode muss etwas zurückgeben, das tut sie bei dir aber nicht.
Außerdem ist dein ansatz falsch, du baust dir eine schleife, welche dann wieder rekursiv die funktion aufruft


----------



## Pattafix299 (13. Mai 2015)

Ok danke. Mit dem Befehl "return" klappt es jetzt. Meiner Meinung darf die Schleife doch rekursiv sein. In der 1. Aufgabe war die Antwort mit der "if" und "else" Funktion, die man dann in eine Schleifen-Funktion umschreiben sollte. Hier unten nochmal die Lösung zur ersten Aufgabe. Bist du dann immer noch der Meinung, dass das der falsche Ansatz ist, also das keine Rekursion auftauchen darf in der "for"-Schleife?


```
import eip.*;


/*
* Class to compute the factorial
*/
public class TA4_1
{
static int factorial( int n )
{   
if( n <= 1 ) {
    return 1;
}
else {
    int erg = n * factorial (n - 1); 
    Std.out.println(n + "! = " + n + "*" + (n-1) + "!");
    Std.out.println(erg);
    return erg;
}
}


public static void main( String[] args )
{
Std.out.println("5! = " + factorial( 5 ) );
Std.out.println("12! = " + factorial( 12 ) );
}
}
```


----------



## InfectedBytes (13. Mai 2015)

Ja bin ich, zumal deine for schleife keine fakultät berechnet:


> Schreiben Sie das Programm zur Berechnung der Fakultät mit der notierten “for-Schleife” anstelle der Rekursion


d.h. du sollst keine rekursion nutzen


----------



## javacc123 (8. Okt 2015)

Hallo,

Kann mir jemand diese Zeile erklären:
int erg = n * factorial (n - 1);

oder wenn ich die Zeile als Return zurückgebe:
return = n*factorial(n-1)

Ich verstehe das nicht so ganz, was ist in diesem Fall das factorial,  bzw. wie sieht diese Rechnung in genau diesem Fall aus?


----------



## InfectedBytes (8. Okt 2015)

einen uralten beitrag ausgraben und darunter eine neue frage stellen ist vielleicht nicht unbedingt die beste idee^^
Besser einen neuen Beitrag erstellen.

ob du direkt per return das ergebnis zurückgibst oder erst zwischenspeicherst ist egal, hier wurde es nur zwischengespeichert, damit man es nochmal kurz auf der konsole ausgeben kann.

factorial ist halt die Methode, welche rekursiv aufgerufen wird.
Angenommen du rufst factorial mit 3 auf, d.h. n=3
-factorial ruft sich dann selbst mit n-1 auf, also mit n=2
--factorial ruft sich dann nochmal selbst auf mit n=1
--da nun die if-Abfrage erfüllt ist, wird 1 zurückgegeben.
-das n dieses aufrufes ist 2, also wird 2*1 zurückgegeben
das n dieses aufrufes ist 3, also wird 3*2 zurückgegeben


----------



## strußi (8. Okt 2015)

wenn ich richtig lese wirst du immer 1 rausbekommen
du solltest in deiner factorial-Methode eine variable erg

Ich hoffe, dass ich jetzt den pädagogischen Mehrwert nicht zerstöre
aber es sollte vlt so aus sehen

```
static int factorial( int n){
        int erg =1;
        if( n <=1){
        } else{
            erg =n *factorial( n -1);
            System.out.println( n + "! =" +n +"*" +( n -1) +"!");
            System.out.println( erg);
        }
        return erg;
    }
```


----------



## InfectedBytes (8. Okt 2015)

strußi hat gesagt.:


> wenn ich richtig lese wirst du immer 1 rausbekommen


ne, es ist schon korrekt so. Es wird die korrekte fakultät berechnet


----------



## strußi (8. Okt 2015)

sry, mein denkfehler.


----------



## javacc123 (9. Okt 2015)

InfectedBytes hat gesagt.:


> einen uralten beitrag ausgraben und darunter eine neue frage stellen ist vielleicht nicht unbedingt die beste idee^^
> Besser einen neuen Beitrag erstellen.
> 
> ob du direkt per return das ergebnis zurückgibst oder erst zwischenspeicherst ist egal, hier wurde es nur zwischengespeichert, damit man es nochmal kurz auf der konsole ausgeben kann.
> ...



Ich checke das immernoch nicht ganz.
Die Methode ruft sich rekursiv auf ok, aber warum wird das N immer weiterrunter gezählt?
Und wird das ergebnis sozusagen zwischengespeichert und aufaddiert?

Wenn ich jetzt z.B. diese Programm habe:

```
static int factorial(int N) {
if (N == 0) return 1;
return N*factorial(N-1);
}
```

Wenn ich jetzt z.B 4 als N nehme:
Kommt zuerst für N = 1, 1 raus.
dann 2*1, dann 3*2 und dann 4*3 und das alles aufaddiert oder wie?
Aber das ist doch falsch.


----------



## InfectedBytes (9. Okt 2015)

immer wenn eine Methode aufgerufen wird, wird ein neuer StackFrame erzeugt, welcher die lokalen Variablen des Aufrufs speichert.
Wenn du also factorial(4) aufrufst, wir ein neuer StackFrame erzeugt, mit der lokalen Variable n=4.
Dann geschieht ein rekursiver Aufruf und es wird ein weiterer StackFrame erzeugt, welcher eine eigene lokale Variable n=3 hat, diese beiden n haben nichts miteinander zu tun, es sind eigenständige lokale Variablen!
Wenn du dann schließlich die Methode mit n=1 aufrufst, wird direkt return 1 ausgeführt und das ergebnis wird an den Aufrufer gegeben. => Der oberste StackFrame (mit n=1) wird entfernt und die Ausführung des darunter liegenden StackFrames wird fortgesetzt, dort ist n=2 und das ergebnis des rekursiven aufrufst ist 1, dann wird 2*1 zurückgegeben usw.

Falls dir das nicht reicht, google am besten mal nach "Rekursion java" oder ähnlichem


----------



## javacc123 (10. Okt 2015)

InfectedBytes hat gesagt.:


> immer wenn eine Methode aufgerufen wird, wird ein neuer StackFrame erzeugt, welcher die lokalen Variablen des Aufrufs speichert.
> Wenn du also factorial(4) aufrufst, wir ein neuer StackFrame erzeugt, mit der lokalen Variable n=4.
> Dann geschieht ein rekursiver Aufruf und es wird ein weiterer StackFrame erzeugt, welcher eine eigene lokale Variable n=3 hat, diese beiden n haben nichts miteinander zu tun, es sind eigenständige lokale Variablen!
> Wenn du dann schließlich die Methode mit n=1 aufrufst, wird direkt return 1 ausgeführt und das ergebnis wird an den Aufrufer gegeben. => Der oberste StackFrame (mit n=1) wird entfernt und die Ausführung des darunter liegenden StackFrames wird fortgesetzt, dort ist n=2 und das ergebnis des rekursiven aufrufst ist 1, dann wird 2*1 zurückgegeben usw.
> ...



Ok habe das jetzt verstanden, dass alte Ergebnis von dem kleinern N wird sozusagen zwischengespeichert und ist relevant für die nächste Berechnung.

Kann man an diesem einfachen und kleinen Beispiel schon die Wirkung des "Dynamischen Programmierens" sehen und ist das einfach nur rekursiv?


----------



## InfectedBytes (10. Okt 2015)

die fakultätsfunktion ist nur eine einfache rekursive funktion. 
Ein gutes beispiel für dynamische programmierung ist die fibonacci folge. Mit einem rekursiven ansatz berechnet man dort sehr viel doppel, während man mit der dynamischen programmierung effektiver ist.


----------

