Wie umkehren Sie eine Zeichenfolge an Ort und Stelle (oder in-place) in JavaScript , wenn es um eine Funktion mit einer return - Anweisung übergeben wird, ohne Einbau-Verwendung von Funktionen ( .reverse()
, .charAt()
etc.)?
javascript
string
reverse
Kobe
quelle
quelle
Antworten:
Solange Sie mit einfachen ASCII-Zeichen arbeiten und gerne integrierte Funktionen verwenden, funktioniert dies:
Wenn Sie eine Lösung benötigen, die UTF-16 oder andere Multi-Byte-Zeichen unterstützt, beachten Sie, dass diese Funktion ungültige Unicode-Zeichenfolgen oder gültige Zeichenfolgen liefert, die lustig aussehen. Vielleicht möchten Sie stattdessen diese Antwort berücksichtigen .
[... s] ist Unicode-fähig, eine kleine Bearbeitung ergibt: -
quelle
return [...s].reverse().join("");
kann funktionieren.Die folgende Technik (oder eine ähnliche) wird üblicherweise verwendet, um eine Zeichenfolge in JavaScript umzukehren:
Tatsächlich sind alle bisher veröffentlichten Antworten eine Variation dieses Musters. Es gibt jedoch einige Probleme mit dieser Lösung. Zum Beispiel:
Wenn Sie sich fragen, warum dies passiert, lesen Sie die interne Zeichenkodierung von JavaScript . (TL; DR:
𝌆
ist ein Astralsymbol und wird von JavaScript als zwei separate Codeeinheiten verfügbar gemacht.)Aber es gibt noch mehr:
Ein guter String zum Testen von String-Reverse-Implementierungen ist der folgende :
Warum? Weil es ein Astralsymbol (
𝌆
) (das in JavaScript durch Ersatzpaare dargestellt wird ) und eine Kombinationsmarke enthält (dieñ
letztemañana
besteht tatsächlich aus zwei Symbolen: U + 006E LATIN SMALL LETTER N und U + 0303 COMBINING TILDE).Die Reihenfolge, in der Ersatzpaare erscheinen, kann nicht umgekehrt werden, da sonst das Astralsymbol nicht mehr in der "umgekehrten" Zeichenfolge angezeigt wird. Aus diesem Grund haben Sie diese
��
Markierungen in der Ausgabe des vorherigen Beispiels gesehen.Kombinationsmarken werden immer auf das vorherige Symbol angewendet, daher müssen Sie sowohl das Hauptsymbol (U + 006E LATIN SMALL LETTER N) als die Kombinationsmarke (U + 0303 COMBINING TILDE) als Ganzes behandeln. Durch Umkehren der Reihenfolge wird die Kombinationsmarke mit einem anderen Symbol in der Zeichenfolge gepaart. Deshalb hatte die Beispielausgabe
ã
stattñ
.Hoffentlich erklärt dies, warum alle bisher veröffentlichten Antworten falsch sind .
Um Ihre erste Frage zu beantworten - wie man eine Zeichenfolge in JavaScript [richtig] umkehrt - habe ich eine kleine JavaScript-Bibliothek geschrieben, die eine Unicode-fähige Zeichenfolgenumkehr ermöglicht. Es hat keine der Probleme, die ich gerade erwähnt habe. Die Bibliothek heißt Esrever ; Der Code befindet sich auf GitHub und funktioniert in nahezu jeder JavaScript-Umgebung. Es wird mit einem Shell-Dienstprogramm / einer Binärdatei geliefert, sodass Sie Zeichenfolgen von Ihrem Terminal aus problemlos umkehren können, wenn Sie möchten.
Weitere Informationen zum „In-Place“ -Teil finden Sie in den anderen Antworten.
quelle
oder
quelle
Detaillierte Analyse und zehn verschiedene Möglichkeiten zum Umkehren einer Zeichenfolge und ihrer Leistungsdetails.
http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/
Leistung dieser Implementierungen:
Implementierung (en) mit der besten Leistung pro Browser
Hier sind diese Implementierungen:
Implementierung 1:
Implementierung 2:
Implementierung 3:
Implementierung 4:
Implementierung 5:
Implementierung 6:
Implementierung 7:
Implementierung 8:
Implementierung 9:
Implementierung 10
quelle
Das ganze "Reverse a String in Place" ist eine veraltete Interviewfrage, die C-Programmierer und Leute, die von ihnen interviewt wurden (vielleicht aus Rache?), Fragen werden. Leider funktioniert der Teil "An Ort und Stelle" nicht mehr, da Zeichenfolgen in nahezu jeder verwalteten Sprache (JS, C # usw.) unveränderliche Zeichenfolgen verwenden, wodurch die gesamte Idee, eine Zeichenfolge zu verschieben, ohne neuen Speicher zuzuweisen, zunichte gemacht wird.
Während die obigen Lösungen tatsächlich eine Zeichenfolge umkehren, tun sie dies nicht, ohne mehr Speicher zuzuweisen, und erfüllen daher nicht die Bedingungen. Sie müssen direkten Zugriff auf die zugewiesene Zeichenfolge haben und in der Lage sein, ihren ursprünglichen Speicherort zu ändern, um sie an Ort und Stelle umkehren zu können.
Persönlich hasse ich solche Interviewfragen wirklich, aber leider bin ich mir sicher, dass wir sie noch viele Jahre sehen werden.
quelle
Verwenden Sie zuerst
Array.from()
, um eine Zeichenfolge in ein Array umzuwandeln, dannArray.prototype.reverse()
um das Array umzukehren und es dannArray.prototype.join()
wieder zu einer Zeichenfolge zu machen.quelle
reverse
Logik wird nicht umgeschrieben .string.split('')
funktioniert nicht. Weitere Erklärungen finden Sie in dieser Antwort .Array.from('foo 𝌆 bar mañana mañana').reverse().join('') == 'anãnam anañam rab 𝌆 oof'
Array.from('foo 𝌆 bar mañana mañana'.normalize('NFC')).reverse().join('')
wird"anañam anañam rab 𝌆 oof"
In ECMAScript 6 können Sie eine Zeichenfolge noch schneller umkehren, ohne die
.split('')
Split-Methode zu verwenden. Der Spread-Operator lautet wie folgt:quelle
('')
string.split('')
ist für die meisten Menschen klarer als[...string]
..split('')
hat das Problem mit Zeichen aus den Zusatzebenen (Surrogatpaar in UTF-16), da sie von der UTF-16 - Code teilt Einheit anstatt Codepunkt . Der Spread-Operator undArray.from()
(meine Präferenz) nicht.Scheint, als wäre ich 3 Jahre zu spät zur Party ...
Leider können Sie nicht, wie bereits erwähnt wurde. Siehe Sind JavaScript-Zeichenfolgen unveränderlich? Benötige ich einen "String Builder" in JavaScript?
Das nächstbeste, was Sie tun können, ist, eine "Ansicht" oder einen "Wrapper" zu erstellen, der eine Zeichenfolge verwendet und alle Teile der von Ihnen verwendeten Zeichenfolgen-API neu implementiert, aber so tut, als wäre die Zeichenfolge umgekehrt. Zum Beispiel:
Demo:
Der Kicker - Folgendes wird vor Ort durch reine Mathematik erledigt, wobei jeder Charakter nur einmal und nur bei Bedarf besucht wird:
Dies führt zu erheblichen Einsparungen, wenn Sie auf eine sehr große Zeichenfolge angewendet werden, wenn Sie nur eine relativ kleine Scheibe davon nehmen.
Ob sich dies lohnt (über das Umkehren als Kopie wie in den meisten Programmiersprachen), hängt stark von Ihrem Anwendungsfall ab und davon, wie effizient Sie die Zeichenfolgen-API erneut implementieren. Wenn Sie beispielsweise nur einen String-Index bearbeiten oder kleine
slice
s odersubstr
s nehmen möchten , sparen Sie Platz und Zeit. Wenn Sie jedoch große umgekehrte Schnitte oder Teilzeichenfolgen drucken möchten, sind die Einsparungen möglicherweise gering und sogar noch schlimmer als bei einer vollständigen Kopie. Ihre "umgekehrte" Zeichenfolge hat auch nicht den Typstring
, obwohl Sie dies möglicherweise mit Prototyping vortäuschen können.Die obige Demo-Implementierung erstellt ein neues Objekt vom Typ ReversedString. Es ist ein Prototyp und daher ziemlich effizient mit nahezu minimalem Arbeitsaufwand und minimalem Platzaufwand (Prototypdefinitionen werden gemeinsam genutzt). Es ist eine träge Implementierung, die ein verzögertes Schneiden beinhaltet. Wann immer Sie eine Funktion wie
.slice
oder.reversed
ausführen, wird eine Indexmathematik ausgeführt. Schließlich, wenn Sie Daten extrahieren (indem Sie implizit.toString()
oder aufrufen.charCodeAt(...)
etwas anderes), werden diese auf "intelligente" Weise angewendet, wobei die geringstmöglichen Daten berührt werden.Hinweis: Die obige Zeichenfolgen-API ist ein Beispiel und möglicherweise nicht perfekt implementiert. Sie können auch nur 1-2 Funktionen verwenden, die Sie benötigen.
quelle
Es gibt viele Möglichkeiten, wie Sie eine Zeichenfolge in JavaScript umkehren können. Ich schreibe drei Möglichkeiten auf, die ich bevorzuge.
Ansatz 1: Umkehrfunktion verwenden:
Ansatz 2: Durchlaufen von Charakteren:
Ansatz 3: Verwenden der Reduktionsfunktion:
Ich hoffe das hilft :)
quelle
Während eines Interviews wurde ich gebeten, eine Zeichenfolge ohne Verwendung von Variablen oder nativen Methoden umzukehren. Dies ist meine Lieblingsimplementierung:
quelle
slice
? : - /Array.prototype.reverse()
.Es gibt mehrere Möglichkeiten, dies zu tun. Sie können Folgendes überprüfen:
1. Traditionell für Schleife (Inkrementieren):
2. Traditionell für Schleife (Dekrementierung):
3. Verwenden der for-of-Schleife
4. Verwenden der forEach / Array-Methode höherer Ordnung:
5. ES6-Standard:
6. Der neueste Weg:
7. Sie können das Ergebnis auch wie folgt erhalten:
quelle
In ES6 haben Sie noch eine Option
quelle
Dies ist der einfachste Weg, den ich denke
quelle
Array.prototype.reverse()
dies am einfachsten, daher die beliebteste Antwort. Natürlich würde es gute Vorkenntnisse in JavaScript erfordern.ODER
// Ausgabe: 'gnirts elpmas'
quelle
[...str]
.Ich weiß, dass dies eine alte Frage ist, die gut beantwortet wurde, aber zu meiner eigenen Unterhaltung habe ich die folgende Umkehrfunktion geschrieben und dachte, ich würde sie teilen, falls sie für andere nützlich wäre. Es behandelt sowohl Ersatzpaare als auch Kombinationsmarken:
Alle Requisiten an Mathias, Punycode und verschiedene andere Referenzen, um mich über die Komplexität der Zeichenkodierung in JavaScript zu unterrichten.
quelle
Sie können nicht, weil JS-Zeichenfolgen unveränderlich sind. Kurze Non-In-Place-Lösung
Code-Snippet anzeigen
quelle
Wenn Sie keine eingebaute Funktion verwenden möchten. Versuche dies
quelle
Die eigentliche Antwort lautet: Sie können es nicht an Ort und Stelle umkehren, aber Sie können eine neue Zeichenfolge erstellen, die umgekehrt ist.
Nur als Übung, um mit Rekursion zu spielen: Manchmal, wenn Sie zu einem Interview gehen, fragt Sie der Interviewer, wie Sie dies mit Rekursion tun sollen, und ich denke, die "bevorzugte Antwort" könnte lauten: "Ich würde dies lieber nicht in Rekursion tun, wie es ist." kann leicht einen Stapelüberlauf verursachen "(weil dies
O(n)
nicht der Fall istO(log n)
. Wenn diesO(log n)
der Fall ist , ist es ziemlich schwierig, einen Stapelüberlauf zu erhalten - 4 Milliarden Elemente könnten von einer Stapelstufe von 32 verarbeitet werden, da 2 ** 32 4294967296 ist. Aber wenn es so istO(n)
Fall , kann es leicht zu einem Stapelüberlauf kommen.Manchmal fragt Sie der Interviewer immer noch: "Nur als Übung, warum schreiben Sie sie nicht immer noch mit Rekursion?" Und hier ist es:
Testlauf:
Ausgabe:
Um zu versuchen , einen Stapelüberlauf immer, ich geändert ,
1000
um10000
in Google Chrome, und berichtete:quelle
Zeichenfolgen selbst sind unveränderlich, aber Sie können problemlos eine umgekehrte Kopie mit dem folgenden Code erstellen:
quelle
quelle
Eine kleine Funktion, die sowohl diakritische Zeichen als auch 2-Byte-Zeichen kombiniert:
Aktualisieren
Eine vollständigere Liste der Kombination von Diakritika lautet:
quelle
isCombiningDiacritic
Funktion so zu bearbeiten , dass sie alle 316 Bereiche enthält. Fühlen Sie sich frei, diese Bearbeitung bereitzustellen, da Sie anscheinend die Daten zur Hand haben.quelle
ohne String in Array umzuwandeln;
Verwenden von Array.reverse ohne Konvertieren von Zeichen in Codepunkte;
quelle
var c = array[i-1]; array[i-1] = array[i]; array[i] = c;
erfordert keine Verkettung des Codepaars. Außerdem sollte die for-Schleife am 1.'\ud83c\ud83c\udfa5'.reverse()
- sie gibt dieselbe Ausgabe aus wie die Eingabe. Das Hinzufügen++i;
innerhalb derif
Anweisung sollte dies beheben.'a\u0303bc'.reverse() === 'cba\u0303'
sollte true zurückgeben.Ich denke, String.prototype.reverse ist ein guter Weg, um dieses Problem zu lösen. der Code wie folgt;
quelle
Verwenden von Array-Funktionen,
quelle
quelle
Mein eigener ursprünglicher Versuch ...
http://jsbin.com/bujiwo/19/edit?js,console,output
quelle
Halten Sie es trocken und einfach albern!
quelle
OK, ziemlich einfach, Sie können eine Funktion mit einer einfachen Schleife erstellen, um die Zeichenfolge für Sie umzukehren, ohne zu verwenden
reverse()
.charAt()
etc wie folgt aus :Zum Beispiel haben Sie diese Zeichenfolge:
Erstellen Sie eine Funktion wie diese, ich nenne es
reverseString
...Und Sie können es so nennen:
Und das Ergebnis wird sein:
quelle
Beste Möglichkeiten, eine Zeichenfolge in JavaScript umzukehren
1) Array.reverse:
Sie denken wahrscheinlich, warten Sie, ich dachte, wir kehren eine Zeichenfolge um. Warum verwenden Sie die Array.reverse-Methode? Mit der String.split-Methode konvertieren wir unseren String in ein Array von Zeichen. Dann kehren wir die Reihenfolge jedes Werts im Array um und konvertieren das Array schließlich mit der Methode Array.join zurück in einen String.
2) Dekrementieren der while-Schleife:
Obwohl diese Lösung ziemlich ausführlich ist, hat sie ihre Vorteile gegenüber der ersten Lösung. Sie erstellen kein Array und verketten lediglich eine Zeichenfolge basierend auf Zeichen aus der Quellzeichenfolge.
Aus Sicht der Leistung würde dieser wahrscheinlich die besten Ergebnisse liefern (obwohl nicht getestet). Bei extrem langen Saiten können die Leistungssteigerungen jedoch aus dem Fenster fallen.
3) Rekursion
Ich finde es toll, wie einfach und klar diese Lösung ist. Sie können deutlich sehen, dass die Methoden String.charAt und String.substr verwendet werden, um einen anderen Wert zu durchlaufen, indem Sie sich jedes Mal selbst aufrufen, bis der String leer ist, von dem der Ternär nur einen leeren String zurückgibt, anstatt die Rekursion zu verwenden, um sich selbst aufzurufen . Dies würde wahrscheinlich die zweitbeste Leistung nach der zweiten Lösung ergeben.
quelle