Ich versuche eine Funktion zu schreiben, die Folgendes ausführt:
- nimmt ein Array von ganzen Zahlen als Argument (z. B. [1,2,3,4])
- erstellt ein Array aller möglichen Permutationen von [1,2,3,4], wobei jede Permutation eine Länge von 4 hat
Die folgende Funktion (ich habe sie online gefunden) führt dazu eine Zeichenfolge als Argument aus und gibt alle Permutationen dieser Zeichenfolge zurück
Ich konnte nicht herausfinden, wie ich es ändern kann, damit es mit einem Array von Ganzzahlen funktioniert (ich denke, das hat etwas damit zu tun, wie einige der Methoden bei Zeichenfolgen anders funktionieren als bei Ganzzahlen, aber ich bin mir nicht sicher. ..)
var permArr = [], usedChars = [];
function permute(input) {
var i, ch, chars = input.split("");
for (i = 0; i < chars.length; i++) {
ch = chars.splice(i, 1);
usedChars.push(ch);
if (chars.length == 0)
permArr[permArr.length] = usedChars.join("");
permute(chars.join(""));
chars.splice(i, 0, ch);
usedChars.pop();
}
return permArr
};
Hinweis: Ich möchte, dass die Funktion Arrays von Ganzzahlen zurückgibt , nicht ein Array von Strings .
Ich brauche wirklich die Lösung, um in JavaScript zu sein. Ich habe bereits herausgefunden, wie das in Python geht
quelle
Etwas spät, möchte aber hier eine etwas elegantere Version hinzufügen. Kann ein beliebiges Array sein ...
Hinzufügen einer ES6 (2015) -Version. Mutiert auch nicht das ursprüngliche Eingabearray. Funktioniert in der Konsole in Chrome ...
So...
Erträge ...
Und...
Erträge ...
quelle
var results = new Array(factorial(inputArr.length)), length=0
, dann ersetzenresults.push(…)
mitresults[length++]=…
var cur, memo = memo || [];
?slice()
inpermute(curr.slice(), m.concat(next))
wirklich notwendig?Der folgende sehr effiziente Algorithmus verwendet die Heap-Methode , um alle Permutationen von N Elementen mit Laufzeitkomplexität in O (N!) Zu generieren:
Der gleiche Algorithmus, der als Generator mit Raumkomplexität in O (N) implementiert ist :
Code-Snippet anzeigen
Leistungsvergleich
Fühlen Sie sich frei, Ihre Implementierung der folgenden Benchmark.js -Testsuite hinzuzufügen :
Code-Snippet anzeigen
Laufzeitergebnisse für Chrome 48:
quelle
yield permutation.slice()
Wenn Sie nicht schneiden, wird nur die zuletzt berechnete Permutation berechnet.quelle
.filter(uniq)
das Ergebnis zusätzlich bearbeiten.[1,2,3].length == 3 && "foo" || "bar"
oder[1,2].length == 3 && "foo" || "bar"
oh mein Gott! es gibt!(or (and (= 3 2) (print "hello!")) (print "goodbye"))
Ich habe verbessert SiGanteng ‚s Antwort .
Jetzt ist es möglich anzurufen
permute
mehr als einmal , dapermArr
undusedChars
jedes Mal gelöscht werden.Code-Snippet anzeigen
quelle
Die folgende Funktion permutiert ein Array eines beliebigen Typs und ruft bei jeder gefundenen Permutation eine angegebene Rückruffunktion auf:
Wenn Sie es so nennen:
Ich denke, es wird genau das tun, was Sie brauchen - ein Array
result
mit den Permutationen des Arrays [1, 2, 3] füllen . Das Ergebnis ist:Etwas klarerer Code in JSFiddle: http://jsfiddle.net/MgmMg/6/
quelle
Die meisten Antworten auf diese Frage verwenden teure Vorgänge wie das kontinuierliche Einfügen und Löschen von Elementen in einem Array oder das wiederholte Kopieren von Arrays.
Stattdessen ist dies die typische Backtracking-Lösung:
Da das Ergebnisarray sehr groß sein wird, ist es möglicherweise eine gute Idee, die Ergebnisse einzeln zu wiederholen, anstatt alle Daten gleichzeitig zuzuweisen. In ES6 kann dies mit Generatoren erfolgen:
quelle
Dies ist eine interessante Aufgabe und hier ist mein Beitrag. Es ist sehr einfach und schnell. Bei Interesse bitte mit mir Kontakt aufnehmen und weiterlesen.
Wenn Sie diesen Job schnell erledigen möchten, müssen Sie sich auf jeden Fall in die dynamische Programmierung einarbeiten. Das heißt, Sie sollten rekursive Ansätze vergessen. Das ist sicher...
OK le_ms Code der die Heap-Methode verwendet, scheint der bisher schnellste zu sein. Nun, ich habe keinen Namen für meinen Algorithmus, ich weiß nicht, ob er bereits implementiert wurde oder nicht, aber er ist sehr einfach und schnell. Wie bei allen dynamischen Programmieransätzen beginnen wir mit dem einfachsten Problem und streben das Endergebnis an.
Angenommen, wir haben eine Reihe von, beginnen
a = [1,2,3]
wir mitFolgen Sie dann diesen drei Schritten.
r
(Ergebnis-) Arrays fügen wir das nächste Element des Eingabearrays hinzu.t
. (Nun, bis auf den ersten, der keine Zeit mit 0 Umdrehungen verschwendet.)r
Interim-Arrays fertig sind,t
sollte es die nächste Ergebnisebene enthalten, damit wirr = t; t = [];
bis zur Länge des Eingabearrays arbeiten und weitermachen könnena
.Das Folgende sind also unsere Schritte;
Also hier ist der Code
In mehreren Tests habe ich gesehen, dass die 120 Permutationen von [0,1,2,3,4] 2000 Mal in 25 ~ 35 ms aufgelöst wurden.
quelle
rotatePerm
(das obige) ist es durchweg 1.2 schneller. Mit FF gibt es keine Konsistenz. Nach mehreren Tests ist es manchmalheapPerm
2-mal schneller , manchmal istrotatePerm
es 1,1-mal schneller. Bei anderen Web-Kit-Browsern wie Opera oder Epiphany ist diesrotatePerm
durchweg 1,1-mal schneller. Mit EdgeheapPerm
ist es jedoch jedes Mal 1,2-mal schneller.permutations
:)Einige von Haskell inspirierte Versionen:
quelle
Antworten Sie, ohne dass ein externes Array oder eine zusätzliche Funktion erforderlich ist
quelle
Die schnellste, effektivste und eleganteste Version (Resorces) heutzutage (2020)
quelle
len % 2 // parity dependent adjacent elements swap
bedeutet und warum es verwendet wird?Hier ist eine coole Lösung
quelle
Hier ist eine andere "rekursivere" Lösung.
Ausgabe:
quelle
Testen Sie es mit:
quelle
Die meisten anderen Antworten verwenden nicht die neuen Funktionen des Javascript-Generators, was eine perfekte Lösung für diese Art von Problem darstellt. Sie benötigen wahrscheinlich jeweils nur eine Permutation im Speicher. Außerdem ziehe ich es vor, eine Permutation eines Bereichs von Indizes zu generieren, da dies mir ermöglicht, jede Permutation zu indizieren und direkt zu einer bestimmten Permutation zu springen sowie eine andere Sammlung zu permutieren.
quelle
quelle
Hier ist eine, die ich gemacht habe ...
Und hier ist es wieder aber weniger knapp geschrieben! ...
So funktioniert es: Wenn das Array länger als ein Element ist, durchläuft es jedes Element und verkettet es mit einem rekursiven Aufruf an sich selbst mit den verbleibenden Elementen als Argument. Das ursprüngliche Array wird nicht mutiert.
quelle
Funktionale Antwort mit flatMap:
quelle
Gibt lexikographisch geordnete Permutationen aus. Funktioniert nur mit Zahlen. In einem anderen Fall müssen Sie die Swap-Methode in Zeile 34 ändern.
quelle
Ähnlich im Geist wie die Haskell-ähnliche Lösung von @crl, jedoch mit
reduce
:quelle
Dies ist ein sehr schöner Anwendungsfall für Map / Reduce:
[].concat(cv,a)
quelle
Hier ist eine minimale ES6-Version. Die Abflachung und ohne Funktionen kann aus Lodash gezogen werden.
Ergebnis:
quelle
quelle
quelle
Ziemlich spät. Immer noch nur für den Fall, dass dies jemandem hilft.
quelle
Ich hatte ein Problem damit, eine Version davon zu erstellen, die versucht, präzise, aber lesbar und rein funktional zu programmieren.
Beachten Sie, dass die Argumentformatierung eine Eingabezeichenfolge in ein Array verwandelt. Ich bin mir nicht sicher, ob das ein bisschen zu magisch ist . Ich bin mir nicht sicher, ob ich es in freier Wildbahn gesehen habe. Für eine echte Lesbarkeit würde ich wahrscheinlich stattdessen
input = [...input]
für die erste Zeile der Funktion tun .quelle
Dies ist eine Implementierung des Heap-Algorithmus (ähnlich dem von @ le_m), außer dass er rekursiv ist.
Es sieht so aus, als wäre es auch ziemlich schneller: https://jsfiddle.net/3brqzaLe/
quelle
Mein erster Beitrag zur Seite. Nach den von mir durchgeführten Tests läuft dieser Code schneller als alle anderen hier genannten Methoden vor diesem Datum. Natürlich ist er minimal, wenn nur wenige Werte vorhanden sind, aber die Zeit nimmt exponentiell zu, wenn zu viele hinzugefügt werden.
quelle
Ich habe einen Beitrag geschrieben , um zu demonstrieren, wie ein Array in JavaScript permutiert wird. Hier ist der Code, der dies tut.
Ruf einfach an
wird funktionieren. Einzelheiten dazu finden Sie in der Erläuterung in diesem Beitrag.
quelle
quelle