Ich weiß, wir können Strings mit StringBuilder
anhängen. Gibt es eine Möglichkeit, Strings voranzustellen (d. H. Strings vor einem String hinzuzufügen), indem wir StringBuilder
verwenden, damit wir die Leistungsvorteile beibehalten können, die StringBuilder
bietet?C# oder Java: Zeichenfolgen mit StringBuilder vorgeben?
Antwort
Die Verwendung der Einfügemethode mit dem Positionsparameter, der auf 0 gesetzt ist, wäre dasselbe wie das Voranstellen (d. H. Einfügen am Anfang).
StringBuilder einfügen für Java: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html#insert() (% 20boolean) –
Das richtige JavaDoc für die relevante API ist : http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html#insert(int,int%20java.lang.CharSequence%29 – ArtB
StringBuilder str = new StringBuilder();
str.Insert(0, "text");
Edit: formated Code
Versuchen Insert()
StringBuilder MyStringBuilder = new StringBuilder("World!");
MyStringBuilder.Insert(0,"Hello "); // Hello World!
Voranstellen einer Zeichenfolge verwendet, wird in der Regel zu kopieren alles benötigen nach dem Einsetzen etwas Punkt zurück in der Backing-Array, so wird es nicht so schnell wie das Anhängen an das Ende.
Aber man kann es so in Java tun (in C# ist es das gleiche, aber die Methode ist Insert
genannt):
aStringBuilder.insert(0, "newText");
Wenn ich Sie richtig verstehe, die insert method sieht aus wie es, was zu tun, Sie wollen. Legen Sie einfach die Zeichenfolge auf 0
versetzt Sie könnten eine Verlängerung Methode versuchen:
/// <summary>
/// kind of a dopey little one-off for StringBuffer, but
/// an example where you can get crazy with extension methods
/// </summary>
public static void Prepend(this StringBuilder sb, string s)
{
sb.Insert(0, s);
}
StringBuilder sb = new StringBuilder("World!");
sb.Prepend("Hello "); // Hello World!
Wenn Sie eine hohe Leistung mit viel wird vorangestellt benötigen, müssen Sie Ihre eigene Version von StringBuilder
(oder Verwendung schreiben von jemand anderem). Mit dem Standard StringBuilder
(obwohl technisch könnte es anders implementiert werden) einfügen erfordern das Kopieren von Daten nach dem Einfügepunkt. Das Einfügen von n Textstücken kann O (n^2) dauern.
Ein naive Ansatz wäre, einen Offset in den Puffer char[]
Puffer sowie die Länge hinzuzufügen. Wenn nicht genügend Platz für einen Vorlauf vorhanden ist, verschieben Sie die Daten um mehr als unbedingt erforderlich. Dies kann die Leistung zurück auf O (n log n) bringen (denke ich). Ein verfeinerterer Ansatz besteht darin, den Puffer zyklisch zu machen. Auf diese Weise wird der Ersatzraum an beiden Enden des Arrays zusammenhängend.
Ich habe es nicht verwendet, aber Ropes For Java klingt faszinierend. Der Projektname ist ein Wortspiel, verwenden Sie eine Rope anstelle einer String für ernsthafte Arbeit. Überwindet die Leistungseinbuße für vorbereitende und andere Vorgänge. Einen Blick wert, wenn du viel davon machst.
Ein Seil ist ein Hochleistungs Ersatz für Saiten. Die Datenstruktur, beschrieben im Detail in „Ropes: eine Alternative zu Strings“, bietet asymptotisch bessere Leistung als sowohl Streich- und Stringbuffer für die gemeinsame Zeichenfolge Modifikationen wie prepend, hängen, löschen und einzufügen. Wie Strings, Seile sind unveränderlich und daher gut geeignet für den Einsatz in Multi-Thread Programmierung.
Sie könnten die Zeichenfolge in umgekehrter Reihenfolge erstellen und dann das Ergebnis umkehren. Sie erhalten einen O (n) -Kosten statt eines O (n^2) Worst-Case-Kosten.
Das funktioniert nur, wenn Sie einzelne anhängen Andernfalls müssten Sie jede hinzugefügte Zeichenfolge umkehren, was die meisten Einsparungen zunichte machen würde, abhängig von der Größe und Anzahl der Zeichenfolgen. – ArtB
Nach den anderen Kommentaren zu urteilen, gibt es keine schnelle Standardmethode, dies zu tun. Die Verwendung von StringBuilders .Insert(0, "text")
ist ungefähr nur 1-3x so schnell wie die Verwendung einer schmerzhaft langsamen String-Verkettung (basierend auf> 10000 concats), daher ist unten eine Klasse, die potenziell tausende Male schneller vorangestellt werden kann!
Ich habe einige andere grundlegende Funktionen enthalten wie append()
, subString()
und length()
usw. Beide Appends und wird vorangestellt von etwa doppelt so schnell variieren langsamer zu 3x als String anhängt. Wie StringBuilder erhöht sich der Puffer in dieser Klasse automatisch, wenn der Text die alte Puffergröße überschreitet.
Der Code wurde ziemlich oft getestet, aber ich kann nicht garantieren, dass er frei von Fehlern ist.
class Prepender
{
private char[] c;
private int growMultiplier;
public int bufferSize; // Make public for bug testing
public int left; // Make public for bug testing
public int right; // Make public for bug testing
public Prepender(int initialBuffer = 1000, int growMultiplier = 10)
{
c = new char[initialBuffer];
//for (int n = 0; n < initialBuffer; n++) cc[n] = '.'; // For debugging purposes (used fixed width font for testing)
left = initialBuffer/2;
right = initialBuffer/2;
bufferSize = initialBuffer;
this.growMultiplier = growMultiplier;
}
public void clear()
{
left = bufferSize/2;
right = bufferSize/2;
}
public int length()
{
return right - left;
}
private void increaseBuffer()
{
int nudge = -bufferSize/2;
bufferSize *= growMultiplier;
nudge += bufferSize/2;
char[] tmp = new char[bufferSize];
for (int n = left; n < right; n++) tmp[n + nudge] = c[n];
left += nudge;
right += nudge;
c = new char[bufferSize];
//for (int n = 0; n < buffer; n++) cc[n]='.'; // For debugging purposes (used fixed width font for testing)
for (int n = left; n < right; n++) c[n] = tmp[n];
}
public void append(string s)
{
// If necessary, increase buffer size by growMultiplier
while (right + s.Length > bufferSize) increaseBuffer();
// Append user input to buffer
int len = s.Length;
for (int n = 0; n < len; n++)
{
c[right] = s[n];
right++;
}
}
public void prepend(string s)
{
// If necessary, increase buffer size by growMultiplier
while (left - s.Length < 0) increaseBuffer();
// Prepend user input to buffer
int len = s.Length - 1;
for (int n = len; n > -1; n--)
{
left--;
c[left] = s[n];
}
}
public void truncate(int start, int finish)
{
if (start < 0) throw new Exception("Truncation error: Start < 0");
if (left + finish > right) throw new Exception("Truncation error: Finish > string length");
if (finish < start) throw new Exception("Truncation error: Finish < start");
//MessageBox.Show(left + " " + right);
right = left + finish;
left = left + start;
}
public string subString(int start, int finish)
{
if (start < 0) throw new Exception("Substring error: Start < 0");
if (left + finish > right) throw new Exception("Substring error: Finish > string length");
if (finish < start) throw new Exception("Substring error: Finish < start");
return toString(start,finish);
}
public override string ToString()
{
return new string(c, left, right - left);
//return new string(cc, 0, buffer); // For debugging purposes (used fixed width font for testing)
}
private string toString(int start, int finish)
{
return new string(c, left+start, finish-start);
//return new string(cc, 0, buffer); // For debugging purposes (used fixed width font for testing)
}
}
Diese Arbeit sollte:
aStringBuilder = "newText" + aStringBuilder;
In .NET funktioniert das perfekt mit Werten vom Typ 'string', aber funktioniert nicht mit Werten vom Typ 'StringBuilder'. Die Antwort von @ScubaSteve funktioniert gut. – Contango
Sie eine Erweiterung für String sich mit einer einfachen Klasse schaffen könnte:
namespace Application.Code.Helpers
{
public static class StringBuilderExtensions
{
#region Methods
public static void Prepend(this StringBuilder sb, string value)
{
sb.Insert(0, value);
}
public static void PrependLine(this StringBuilder sb, string value)
{
sb.Insert(0, value + Environment.NewLine);
}
#endregion
}
}
Dann fügen Sie einfach:
using Application.Code.Helpers;
Ganz oben in jeder Klasse, die Sie verwenden möchten Wenn Sie intelli-sense mit einer StringBuilder-Variablen verwenden, werden die Methoden Prepend und PrependLine angezeigt. Denken Sie daran, dass Sie Prepend in umgekehrter Reihenfolge vorgeben müssen, als wenn Sie Appending verwenden würden.
- 1. java outOfMemoryError mit stringbuilder
- 2. C# StringBuilder mit Anführungszeichen (forJSON)
- 3. C# GDI + DrawString() mit StringBuilder?
- 4. Alle CSS-Selektoren vorgeben
- 5. C# PInvoice out Zeichenfolgen-Deklaration
- 6. Formlos: Vorgeben. Implizit nicht gefunden
- 7. Java - Zeichenfolgen mit Zeilenvorschubzeichen drucken
- 8. StringBuilder Marshalling Problem in C#
- 9. Haben Java-Kommentare mit mehreren Zeilen Zeichenfolgen?
- 10. Vergleichen von Zeichenfolgen in Java mit "==" -Operator
- 11. Parametrisierte Zeichenfolgen in Java
- 12. InputSource mit StringBuilder?
- 13. StringBuilder AppendFormat mit @
- 14. Java Matcher.appendReplacement() und Matcher.appendTail() für StringBuilder?
- 15. Tabellennamen beim MySQL-Datenbankexport vorgeben
- 16. StringBuilder in Flex
- 17. Java: StringBuilder setCharAt funktioniert nicht richtig
- 18. Wie kann mit StringBuilder große Textdateien in Java gelesen werden?
- 19. Veränderliche Zeichenfolgen in Java
- 20. Kann ich ein Element in SASS vorgeben?
- 21. replaceAll für StringBuilder mit Regex-Unterstützung?
- 22. Java RegEx prüft auf eine oder mehrere formatierte Zeichenfolgen
- 23. Java Vergleichen von zwei Zeichenfolgen mit Platzhalterwerten
- 24. C++ - Alphabetische Zeichenfolgen
- 25. Formatieren von Zeichenfolgen in Java
- 26. C# zu C++ - Prozess mit WM_COPYDATA übergeben struct mit Zeichenfolgen
- 27. Regex Ersetzungen in einem StringBuilder
- 28. Übergabe von C++ - Zeichenfolgen nach Wert oder Verweis
- 29. .NET StringBuilder - prüfen, ob endet mit Zeichenfolge
- 30. StringBuilder vs XmlTextWriter
Ich verstehe Ihre Frage nicht –
Prepend. Das Wort wird vorangestellt. Preadding einer Zeichenfolge muss etwas wie das Hinzufügen zu beiden Enden einer Zeichenfolge auf einmal sein, denke ich? –