2016-07-10 18 views
1

Auf meine Frage zu vereinfachen bitten, lassen Sie uns alle Permutationen eines Arrays Druck betrachten, ohne Wiederholung. Also, wenn {1,2,3} das Array war, wäre die Ausgabe der folgendenWie Wert von allen bisherigen Rahmen weitergeben (höhere Frames) zu einem unteren Rahmen während Rekursion

1 2 3 
1 3 2 
2 1 3 
2 3 1 
3 1 2 
3 2 1 
count == 6 

Wie kann ich eine Zählung aller Elemente passieren, die niedriger ist an einem Rahmen bereits Teil des Arrays sind. Ich meine, sagen wir, in den ersten beiden Frames der Rekursion habe ich die Elemente 1 und 2 in meinem Stack. Ich muss dem Rahmen unten sagen, dass er alle Elemente außer 1 und 2 verwenden kann, da es bereits verwendet wird.

Bitte siehe meinen Code unten, wo ich ein Array aller auftretenden Elemente als Teil des Funktionsaufrufes für den Rahmen unten passieren. Aber ich muss auch die Elemente des Arrays für andere rekursive Aufrufe im selben Frame speichern und wiederherstellen, da Java keine Kopie des Arrays in jedem Frame speichert und das Übergeben von Referenzen dazu führt, dass das Array überschrieben wird.

import java.util.Arrays; 

public class SendfromHigherFrameToLowerFrame { 
    static int count = 0; 

    public static void main(String[] args) { 
     int[] a = {1,2,3}; 

     int[] stack = new int[3]; 
     fun(a, stack, 0); 

     System.out.println("count == "+count); 
    } 

    static void fun(int[] a, int[] stack, int frame) 
    { 
     if(a.length == frame) 
     { 
      count++; 
      print(stack); 
      return; 
     } 

     for(int i = 0;i<a.length;i++) 
     { 
      //save stack 
      int[] temp = new int[stack.length]; 
      save(stack, temp); 
      if(isValid(stack, a[i]) == true) 
      { 
       stack[frame] = a[i]; 
       fun(a, stack, frame+1); 
       //restore stack 
       restore(temp, stack); 
      } 
     } 
    } 

    static void save(int[] source, int[] destination) 
    { 
     for(int i = 0;i<source.length;i++) 
      destination[i] = source[i]; 
    } 

    static void restore(int[] source, int[] destination) 
    { 
     for(int i = 0;i<source.length;i++) 
      destination[i] = source[i]; 
    } 

    static boolean isValid(int[] a, int key) 
    { 
     for(int i = 0;i<a.length;i++) 
     { 
      if(a[i] == key) 
       return false; 
     } 
     return true; 
    } 

    static void print(int[] a) 
    { 
     for(int x : a) 
      System.out.print(x + " "); 
     System.out.println(); 
    } 
} 

Bitte schlagen Sie Verbesserungen des Codes vor, oder eine einfachere Methode zum Weiterleiten von Elementen durch den Aufruf.

PS: Bitte beachten Sie, dass Permutationen ist nicht meine ursprüngliche Frage zu erzeugen, und ich verstehe, gibt es einfachere Möglichkeiten, es zu tun, es ist nur für den Zweck meiner Frage der Vermittlung.

+0

Warum nicht Ihre Methoden nicht statisch konvertieren dann eine Instanz Feld verwenden? .. –

Antwort

1

Da es keine Möglichkeit gibt, ein Primitiv per Referenz in Java zu übergeben, können Sie nicht einfach einen int erstellen und den Aufrufstapel weiterleiten. Es gibt drei Workarounds für dieses Problem:

  • Verwenden Sie eine veränderbare Klasse, wie zum Beispiel einer Anordnung eines einzelnen int oder AtomicInteger. Dieser Ansatz grenzt jedoch an einen Missbrauch von Arrays und veränderbaren Klassen.
  • Erstellen Sie eine Instanzvariable oder eine statische Variable, so wie Sie es gemacht haben. Dies ist alles andere als ideal, da Ihre rekursive Funktion nicht einspringt und daher viel schwieriger zu testen ist.
  • Geben Sie den geänderten Wert aus der Methode zurück und fügen Sie ihn einer lokalen Variablen innerhalb der rekursiven Methode hinzu, um ihn als eigenen Rückgabewert zu übergeben. Dieser Ansatz ist zwar gut, bietet jedoch nur einen einzigen Rückgabewert und erfordert, dass Sie beim Schreiben Ihres Codes sehr vorsichtig vorgehen.

Hier ist, wie Sie funktionieren kann, die letzte oben beschriebenen Ansatz zu implementieren modifiziert werden:

static int fun(int[] a, int[] stack, int frame) { 
    if(a.length == frame) { 
     print(stack); 
     return 1; 
    } 
    int res = 0; 
    for(int i = 0;i<a.length;i++) { 
     //save stack 
     int[] temp = new int[stack.length]; 
     save(stack, temp); 
     if(isValid(stack, a[i]) == true) { 
      stack[frame] = a[i]; 
      res += fun(a, stack, frame+1); 
      //restore stack 
      restore(temp, stack); 
     } 
    } 
    return res; 
} 

Demo.

Hinweis: Es versteht sich, dass Ihre Übung nicht tun müssen all dies, weil count immer gleich stack.length ist.

+0

für die dritte Kugel Sie erwähnt hat, könnten Sie bitte Ihre Antwort mit einem bearbeiten Pseudocode.Ich habe es nicht vollständig verstanden. – saltandwater

+0

@saltandwater Bitte beachten Sie die Änderung. – dasblinkenlight

+0

Danke. Aber kleine Sprachprüfung hier. Betrachten Sie eine Anrufliste wie Spaß (5), Spaß (4), Spaß (3), Spaß (2), Spaß (1), Spaß (0); Hier, wenn ich "höheren Rahmen" meine, 5 und Spaß (4) ist der untere Rahmen. Ich habe gefragt, wie ein Wert von Spaß (5) über Spaß (4), Spaß (3), Spaß (2) bis hin zu Spaß (0) weitergegeben werden kann. Das heißt, wenn ein Element in Spaß (5) aufgenommen wird, brauche ich auch Spaß (0), um zu wissen, dass es genommen wurde und nicht verwendet werden kann. Ich hatte den Eindruck, dass Ihr dritter Punkt mehr auf die Rückkehr von einem niedrigeren Frame zu einem höheren Frame gerichtet ist, damit es konsistent mit meiner Verwendung von "Lower" und "High" bleibt. ? – saltandwater

-1

ich nicht von einem Rahmen beantworten will Wert vorbei, aber ich habe eine einfache Möglichkeit für Permutationen.

void Calc(String a, String b){ 


    if (a.equals("")) { 
     System.out.println(a); 
     return; 
    } else { 
     for (int i = 0; i < a.length(); i++) { 
      Calc(removeFirst(a, i), b + a.charAt(i)); 
     } 

    } 

    public static void main(String[] args){ 
     Calc("123", ""); 
    } 

Goodluck

Milad

+0

Ich glaube nicht, dass dies wirklich die Frage beantwortet. Das OP sagte: "Das Erzeugen von Permutationen ist nicht meine ursprüngliche Frage ... es dient ausschließlich dem Zweck, meine Frage zu vermitteln", bei der es darum geht, einen Wert aus früheren Frames zu übergeben. –