2012-05-24 4 views
13

Ich habe FunktionWie kann man die Ackermann-Funktion in nicht-rekursivem Stil umschreiben?

public static int func(int M,int N){ 
    if(M == 0 || N == 0) return M+N+1; 
    return func(M-1, func(M, N-1)); 
} 

Wie es in nicht-rekursive Stil neu zu schreiben? Vielleicht ist es die Implementierung eines Algorithmus?

+2

Haben Sie versucht, eine Schleife zu verwenden? – assylias

+1

'while (M! = 0 || N! = 0) {\\ todo}' – BILL

+3

Riecht wie Hausaufgaben. Was hast du probiert? –

Antwort

14

Nicht ganz O (1), aber definitiv nicht rekursiv.

public static int itFunc(int m, int n){ 
    Stack<Integer> s = new Stack<Integer>; 
    s.add(m); 
    while(!s.isEmpty()){ 
     m=s.pop(); 
     if(m==0||n==0) 
      n+=m+1; 
     else{ 
      s.add(--m); 
      s.add(++m); 
      n--; 
     } 
    } 
    return n; 
} 
+0

Ich bekomme 4 für m = 2, n = 1. n = 1, s = {2} -> n = 1, m = 2 -> n = 0, s = {3,1} -> n = 0, m = 3 -> n = 3 + 1 = 4. Es sei denn, meine Mathematik war falsch auf f (2,1) auf meiner Antwort? –

+0

Ja, deine Mathematik ist falsch. Ich überprüfte es gegen den Code, den er zur Verfügung stellte. –

+0

Wo bin ich falsch gelaufen? Ich muss eine Trennung sehen, denn wenn ich meine Berechnungen durchführe, bekomme ich eine korrekte Antwort.: S –

5

Das sieht aus wie Hausaufgaben, so dass ich Ihnen keine Antwort geben, aber ich werde dich in die richtige Richtung führen:

Wenn Sie die Rekursion Zusammenbruch wollen, könnte es sinnvoll sein, für Sie alles aufzulisten die Werte, während sie fortschreiten, wobei m = {0 ... x} n = {0 ... y}.

Zum Beispiel:

m = 0, n = 0 = f(0,0) = M+N+1 = 1 
m = 1, n = 0 = f(1,0) = M+N+1 = 2 
m = 1, n = 1 = f(1,1) = f(0,f(1,0)) = f(0,2) = 3 
m = 2, n = 1 = f(2,1) = f(1,f(2,0)) = f(1,3) = f(0,f(1,2)) = f(0,f(0,f(1,1)) 
      = f(0,f(0,3))   = f(0,4) = 5 

Mit diesem können Sie mit einer nicht-rekursive Beziehung kommen (eine nicht-rekursive Funktionsdefinition), die Sie verwenden können.

Edit: So sieht es aus wie the Ackermann function, eine insgesamt berechenbare Funktion, die nicht primitive rekursive ist.

+0

@KDiTraglia Du hast Recht- Ich habe es sogar richtig in der dritten Gleichung. Danke :) –

0

Dies ist eine richtige Version, die bereits von mir untersucht.

public static int Ackermann(int m, int n){ 
Stack<Integer> s = new Stack<Integer>; 
s.add(m); 
while(!s.isEmpty()){ 
    m=s.pop(); 
    if(m==0) { n+=m+1; } 
    else if(n==0) 
    { 
     n += 1; 
     s.add(--m); 
    } 
    else{ 
     s.add(--m); 
     s.add(++m); 
     n--; 
    } 
} 
return n; 
} 
+0

Dies scheint eine sehr geringfügige Variation der Antwort von @ LightyearBuzz zu sein, bei der Sie die Optimierung des Stapels für den Fall "n == 0" durchführen, um jedes Inkrement nacheinander durchzuführen, anstelle von Lightyears "n + = m + 1" ; '. Hast du das Ganze wirklich selbst geschrieben, oder wird das meistens (ohne Credit) von der anderen Antwort kopiert? –

+0

Diese Antwort ändert nur leicht die Antwort von LightyearBuzz, und es tut mir leid, dass ich seinen Code benutzt habe, ohne ihn zu informieren. Da ich gesehen habe, dass sein Code nicht jedes Beispiel passieren kann, habe ich eine kleine Änderung vorgenommen, um es zu korrigieren. Wenn Sie es nicht mögen, kann ich es löschen. Aber ich möchte nur, dass die Leute die richtige Antwort sehen können ^^ –

+0

Was Sie tun sollten, ist [bearbeiten] Sie Ihre Antwort, um zu sagen, welchen Bug es behebt. (d. h. welcher Eingang gibt die falsche Antwort). z.B. "Die Antwort von LightyearBuzz ist falsch für' A (blah, blah) '. Ich habe es behoben, indem ich blah blah geändert habe. Hier ist der vollständige Code:" –