Frage

muss ich ohne Ziffern gemacht Wiederholungen alle Variationen generieren 0 -. 9

Länge von ihnen von 1 bis 10 sein könnte, ich weiß wirklich nicht, wie es zu lösen, vor allem, wie Wiederholungen zu vermeiden.

Beispiel:    Länge der Variante: 4    zufällige Variationen: 9856, 8753, 1243, 1234 usw. (aber nicht 9985 - enthalten Wiederholung)

Ich wäre wirklich dankbar, wenn mir jemand mit diesem Problem helfen kann, vor allem einige Code und Hinweise zu geben.

War es hilfreich?

Lösung

Das Schlüsselwort zu suchen ist Permutation . Es gibt eine Fülle von Quellcode frei zur Verfügung, führt sie.

Was halten es Wiederholung befreien ich eine einfache rekursive Ansatz vorschlagen: für jede Ziffer, die Sie haben die Auswahl davon in Ihre Variation nehmen oder nicht, so dass Ihre Rekursion zählt durch die Ziffern und gabelt sich in zwei rekursive Aufrufe, eine, in der die digit enthalten ist, eines, bei dem es ausgeschlossen wird. Dann, nachdem die letzte Ziffer jeder Rekursion erreicht im Wesentlichen gibt Ihnen eine (einmalige, sortiert) Liste der Wiederholung freien Stellen. Anschließend können Sie alle möglichen Permutationen dieser Liste erstellen und alle diese Permutationen kombinieren, um Ihr Endergebnis zu erzielen.

(Das gleiche wie duffymo sagte: Ich werde keinen Code für die Versorgung)

Erweiterte Anmerkung: die Rekursion basiert auf 0/1 (Ausschluss, Inklusion), die direkt an Bits übersetzt werden kann, daher ganze Zahlen. Deshalb, um alle möglichen Zahlenkombinationen zu erhalten, ohne tatsächlich die Durchführung der Rekursion selbst Sie einfach alle Zahlen 10-Bit-Integer verwenden könnte und durchlaufen sie. Dann interpretiert die Zahlen sind, so dass ein Satz entspricht das Bit der Ziffer in der Liste darunter, dass permutiert werden muss.

Andere Tipps

Hier ist mein Java-Code. Fühlen Sie sich frei zu fragen, ob Sie nicht verstehen. Der wichtigste Punkt hier ist:

  
      
  1. Art wieder Zeichen-Array. zum Beispiel: a1 a2 a3 b1 b2 b3 .... (a1 = a2 = a3)
  2.   
  3. erzeugen Permutation und immer halten Bedingung: Index von a1   
import java.util.Arrays;

public class PermutationDup {

    public void permutation(String s) {
        char[] original = s.toCharArray();
        Arrays.sort(original);
        char[] clone = new char[s.length()];
        boolean[] mark = new boolean[s.length()];
        Arrays.fill(mark, false);
        permute(original, clone, mark, 0, s.length());
    }

    private void permute(char[] original, char[] clone, boolean[] mark, int length, int n) {
        if (length == n) {
            System.out.println(clone);
            return;
        }

        for (int i = 0; i < n; i++) {
            if (mark[i] == true) continue;
            // dont use this state. to keep order of duplicate character
            if (i > 0 && original[i] == original[i-1] && mark[i-1] == false) continue;
            mark[i] = true;
            clone[length] = original[i];
            permute(original, clone, mark, length+1, n);
            mark[i] = false;
        }

    }

    public static void main(String[] args) {
        PermutationDup p = new PermutationDup();
        p.permutation("abcab");
    }
}

Ich habe den folgenden Code erstellte Permutationen zu erzeugen, wo Ordnung wichtig ist und ohne Wiederholung. Es macht Gebrauch von Generika für Permutation jede Art von Objekt:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Permutations {

    public static <T> Collection<List<T>> generatePermutationsNoRepetition(Set<T> availableNumbers) {
        Collection<List<T>> permutations = new HashSet<>();

        for (T number : availableNumbers) {
            Set<T> numbers = new HashSet<>(availableNumbers);
            numbers.remove(number);

            if (!numbers.isEmpty()) {
                Collection<List<T>> childPermutations = generatePermutationsNoRepetition(numbers);
                for (List<T> childPermutation : childPermutations) {
                    List<T> permutation = new ArrayList<>();
                    permutation.add(number);
                    permutation.addAll(childPermutation);
                    permutations.add(permutation);
                }
            } else {
                List<T> permutation = new ArrayList<>();
                permutation.add(number);
                permutations.add(permutation);
            }
        }

        return permutations;
    }
}

Stellen Sie sich eine magische Funktion hatte - eine Reihe von Ziffern angegeben, es wird Ihnen die richtigen Permutationen zurückzukehren.

Wie können Sie diese Funktion verwenden, um eine neue Liste von Permutationen mit nur einem zusätzlichen Stelle zu produzieren?

z. B.

Wenn ich Ihnen eine Funktion namens permute_three(char[3] digits), und ich Ihnen sagen, dass es funktioniert nur für Ziffern 0, 1, 2, wie können Sie eine Funktion schreiben, die 0 permutieren kann, 1, 2, 3, mit der gegebenen permute_three Funktion ?

...

, wenn Sie das gelöst, was fällt Ihnen auf? können Sie es verallgemeinern?

Dollar es ist einfach:

@Test
public void generatePermutations() {
    // digits is the string "0123456789"
    String digits = $('0', '9').join();

    // then generate 10 permutations
    for (int i : $(10)) {
        // shuffle, the cut (0, 4) in order to get a 4-char permutation
        System.out.println($(digits).shuffle().slice(4));
    }
}

Der Code dafür ist, ähnlich der ohne Duplikate, mit dem Zusatz einer if-else statement.Check diese

Permutation ohne Wiederholung auf Theorem basiert, ist die Menge der Ergebnisse der faktoriellen Anzahl der Elemente (in diesem Fall Zahlen). In Ihrem Fall 10! ist 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 3628800. Der Beweis, warum es genau richtig ist auch richtige Lösung für die Erzeugung ist. Nun ja, wie. Am ersten Position, dh von links Sie 10 Zahlen haben kann, auf der zweiten Position, die Sie nur 9 Zahlen haben kann, weil eine Nummer auf der Position auf der linken Seite ist und wir die gleiche Anzahl usw. nicht wiederholen kann (der Beweis wird durch mathematische Induktion getan ). So wie erste zehn Ergebnisse zu generieren? Nach meinem Wissen ist er einfachste Weg zyklische Verschiebung zu verwenden. Es bedeutet, die Reihenfolge der Zahl Verschiebung nach links auf einer Position (oder rechts, wenn Sie wollen) und die Anzahl Überlauf, der auf der leeren Stelle zu setzen. Es bedeutet für den ersten zehn Ergebnisse:

  

10 9 8 7 6 5 4 3 2 1 |   9 8 7 6 5 4 3 2 1 10
  8 7 6 5 4 3 2 1 10 9
  7 6 5 4 3 2 1 10 9 8
  6 5 4 3 2 1 10 9 8 7
  5 4 3 2 1 10 9 8 7 6
  ...

Die erste Zeile Grund Probe vorhanden ist, so ist es die gute Idee, es in Satz vor der Erzeugung zu setzen. Vorteil ist, dass im nächsten Schritt werden Sie das gleiche Problem lösen müssen, um unerwünschte Duplizitäten zu vermeiden.

Im nächsten Schritt drehen rekursiv nur 10-1 Zahlen 10-1 Zeiten etc. Es bedeutet für die ersten 9 Ergebnisse in Schritt zwei:

  

10 9 8 7 6 5 4 3 2 1 |   10 8 7 6 5 4 3 2 1 9
  10 7 6 5 4 3 2 1 9 8
  10 6 5 4 3 2 1 9 8 7
  10 5 4 3 2 1 9 8 7 6
  ...

etc, bemerkt, dass erste Zeile vorhanden aus dem vorherigen Schritt, so dass es nicht zu erzeugten Satz wieder hinzugefügt werden.

Algorithmus rekursiv tun genau das, was oben erläutert. Es ist möglich, alle 3628800 Kombinationen für 10 zu erzeugen !, weil Anzahl der Verschachtelung die gleiche wie Anzahl der Elemente in einem Array ist (es bedeutet, in Ihrem Fall für 10 Nummern es ca. 5min verweilt. Auf meinem Computer), und Sie müssen über genügend Speicher wenn Sie alle Kombinationen in Array behalten wollen.

Es gibt Lösung.

package permutation;

/** Class for generation amount of combinations (factorial)
 * !!! this is generate proper permutations without repeating and proper amount (počet) of rows !!!
 *
 * @author hariprasad
 */
public class TestForPermutationII {
  private static final String BUMPER = "*";
  private static int counter = 0;
  private static int sumsum = 0;
  // definitoin of array for generation
  //int[] testsimple = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  int[] testsimple = {1, 2, 3, 4, 5};
  private int ELEMNUM = testsimple.length;
  int[][] shuff;

  private String gaps(int len) {
    String addGap = "";
    for(int i=0; i <len; i++)
      addGap += "  ";
    return addGap;
  }

  /** Factorial computing */
  private int fact(int num) {
    if (num > 1) {
      return num * fact(num - 1);
    } else {
      return 1;
    }
  }

  /** Cyclic shift position to the left */  
  private int[] lShiftPos(int[] arr, int pos) {
    int[] work = new int[ELEMNUM];
    int offset = -1;
    for (int jj = 0; jj < arr.length; jj++) {
      if (jj < pos) {
        work[jj] = arr[jj];
      } else if (jj <= arr.length - 1) {
        if (jj == pos) {
          offset = arr[pos]; // last element
        }
        if (jj != (arr.length - 1)) {
          work[jj] = arr[jj + 1];
        } else {
          work[jj] = offset;
        }
      }
    }
    return work;
  }

  private String printBuff(int[] buffer) {
    String res = "";
    for (int i= 0; i < buffer.length; i++) {
      if (i == 0) 
        res += buffer[i];
      else
        res += ", " + buffer[i];
    }
    return res;
  };

  /** Recursive generator for arbitrary length of array */
  private String permutationGenerator(int pos, int level) {
    String ret = BUMPER;
    int templen = counter;
    int[] work = new int[ELEMNUM];
    int locsumread = 0;
    int locsumnew = 0;
    //System.out.println("\nCalled level: " + level);

    for (int i = 0; i <= templen; i++) {
      work = shuff[i];
      sumsum++;
      locsumread++;
      for (int ii = 0; ii < pos; ii++) {
        counter++;
        sumsum++;
        locsumnew++;
        work = lShiftPos(work, level); // deep copy
        shuff[counter] = work;
      }
    }

    System.out.println("locsumread, locsumnew: " + locsumread + ", " + locsumnew);
    // if level == ELEMNUM-2, it means no another shift
    if (level < ELEMNUM-2) {
      ret = permutationGenerator(pos-1, level+1);
      ret = "Level " + level + " end.";
      //System.out.println(ret);
    }
    return ret;
  }

  public static void main(String[] argv) {
    TestForPermutationII test = new TestForPermutationII();
    counter = 0;
    int len = test.testsimple.length;
    int[] work = new int[len];

    test.shuff = new int[test.fact(len)][];

    //initial
    test.shuff[counter] = test.testsimple;
    work = test.testsimple; // shalow copy

    test.shuff = new int[test.fact(len)][];
    counter = 0;
    test.shuff[counter] = test.testsimple;
    test.permutationGenerator(len-1, 0);

    for (int i = 0; i <= counter; i++) {
      System.out.println(test.printBuff(test.shuff[i]));
    }

    System.out.println("Counter, cycles: " + counter + ", " + sumsum);
  }
}

Intensität (Anzahl der Zyklen) des Algorithmus ist die Summe der unvollständigen factorials der Zahl der Mitglieder. So gibt es Überhang, wenn Teilsatz wird wieder gelesen nächste Teilmenge zu erzeugen, so Intensität ist:

  

n! + N! / 2! + N! / 3! + ... + n! / (N-2)! + N! (N-1)!

Es gibt eine Lösung, die nicht von mir ist, aber es ist sehr schön und anspruchsvoll.

    package permutations;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * @author Vladimir Hajek
 *
 */
public class PermutationSimple {
    private static final int MAX_NUMBER = 3;

    Set<String> results = new HashSet<>(0);

    /**
     * 
     */
    public PermutationSimple() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @param availableNumbers
     * @return
     */
    public static List<String> generatePermutations(Set<Integer> availableNumbers) {
        List<String> permutations = new LinkedList<>();

        for (Integer number : availableNumbers) {
            Set<Integer> numbers = new HashSet<>(availableNumbers);
            numbers.remove(number);

            if (!numbers.isEmpty()) {
                List<String> childPermutations = generatePermutations(numbers);
                for (String childPermutation : childPermutations) {
                    String permutation = number + childPermutation;
                    permutations.add(permutation);
                }
            } else {
                permutations.add(number.toString());
            }
        }

        return permutations;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        Set<Integer> availableNumbers = new HashSet<>(0);

        for (int i = 1; i <= MAX_NUMBER; i++) {
            availableNumbers.add(i);
        }

        List<String> permutations = generatePermutations(availableNumbers);
        for (String permutation : permutations) {
            System.out.println(permutation);
        }

    }
}

Ich denke, das ist die hervorragende Lösung.

Kurz hilfreich Permutation Indizierung Wissen

Erstellen Sie eine Methode, die die korrekte Permutation erzeugt, da ein Indexwert zwischen {0 und N! -1} für „Null indiziert“ oder {1 und N!} Für „einen indiziert“.

Erstellen einer zweiten Methode einer „for-Schleife“ enthält, wobei die untere Grenze 1 und der oberen Grenze ist N !. z .. "für (i; i <= N !; i ++)". für jede Instanz des Schleifen Anruf die erste Methode, i als Argument übergeben

scroll top