169 Stimmen

Wie können wir Zeichenfolgen mit StringBuilder vorangestellt?

Ich weiß, dass wir Strings anhängen können mit StringBuilder . Gibt es eine Möglichkeit, Zeichenketten voranzustellen (d. h. Zeichenketten vor einer Zeichenkette hinzuzufügen), indem man StringBuilder damit wir die Leistungsvorteile behalten können, die StringBuilder Angebote?

6voto

bright Punkte 4418

Sie könnten die Zeichenkette in umgekehrter Reihenfolge aufbauen und dann das Ergebnis umkehren. Dabei entstehen O(n)-Kosten anstelle von O(n^2)-Kosten im schlimmsten Fall.

4voto

Shawn Punkte 1029

Wenn ich Sie richtig verstehe, ist die Einfügemethode Sieht so aus, als würde es das tun, was Sie wollen. Fügen Sie einfach die Zeichenfolge bei Offset 0 ein.

4voto

Sam Barnum Punkte 10220

Ich habe es nicht benutzt, aber Seile für Java Klingt faszinierend. Der Projektname ist ein Wortspiel, verwenden Sie ein Seil anstelle einer Zeichenfolge für ernsthafte Arbeit. Umgeht die Leistungseinbußen beim Prepending und anderen Operationen. Es lohnt sich, einen Blick darauf zu werfen, wenn Sie dies häufig tun werden.

Ein Seil ist ein hochleistungsfähiges Ersatz für Strings. Die Datenstruktur, ausführlich beschrieben in "Seile: eine Alternative zu Strings", bietet eine asymptotisch bessere Leistung als sowohl String als auch StringBuffer für gängige String Modifikationen wie Prepend, Append, Löschen und Einfügen. Wie Strings, sind Strings unveränderlich und daher für die Verwendung in der Multithreading-Programmierung Programmierung.

3voto

boj Punkte 10213

Versuchen Sie es mit Einfügen()

StringBuilder MyStringBuilder = new StringBuilder("World!");
MyStringBuilder.Insert(0,"Hello "); // Hello World!

3voto

Dan W Punkte 3262

Nach den anderen Kommentaren zu urteilen, gibt es keine schnelle Standardmethode für diese Aufgabe. Die Verwendung von StringBuilder's .Insert(0, "text") ist ungefähr nur 1-3x so schnell wie die schmerzhaft langsame String-Verkettung (basierend auf >10000 Verkettungen), daher gibt es unten eine Klasse, die potenziell tausendmal schneller ist!

Ich habe einige andere grundlegende Funktionen hinzugefügt, wie z. B. append() , subString() y length() usw. Sowohl Appends als auch Prepends sind etwa doppelt so schnell bis dreimal langsamer als StringBuilder-Appends. Wie bei StringBuilder wird der Puffer in dieser Klasse automatisch vergrößert, wenn der Text die alte Puffergröße übersteigt.

Der Code wurde ausgiebig 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)
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X