Domanda

So che possiamo aggiungere stringhe utilizzando StringBuilder. C'è un modo siamo in grado di anteporre le stringhe (vale a dire aggiungere stringhe di fronte a una stringa) utilizzando StringBuilder modo che possiamo mantenere i vantaggi di prestazioni che StringBuilder offerta?

È stato utile?

Soluzione

Utilizzando il metodo inserto con il parametro di posizione impostato a 0 sarebbe la stessa prepending (cioè inserendo all'inizio).

An example is : varStringBuilder.insert(0, "someThing");

Funziona sia per C # e Java

Altri suggerimenti

Anteporre una stringa di solito richiedono copiando tutto dopo il punto di inserimento indietro alcuni nella matrice di supporto, in modo che non sarà più velocemente aggiungendo alla fine.

Ma si può fare in questo modo in Java (in C # è la stessa, ma il metodo è chiamato Insert):

aStringBuilder.insert(0, "newText");

Se avete bisogno di prestazioni elevate con un sacco di antepone, è necessario scrivere la propria versione di StringBuilder (o usare qualcun altro). Con il StringBuilder standard (anche se tecnicamente potrebbe essere implementata in modo diverso) inserire richiedono la copia dei dati dopo il punto di inserimento. Inserimento di n pezzo di testo può richiedere O tempo (n ^ 2).

Un approccio semplice sarebbe quello di aggiungere un offset nel buffer char[] supporto, nonche la lunghezza. Quando non c'è abbastanza spazio per un prepend, spostare i dati da più di quanto sia strettamente necessario. Questo può portare le prestazioni giù a O (n log n) (credo). Un approccio più raffinato è quello di rendere il ciclico buffer. In tal modo lo spazio libero a entrambe le estremità della matrice diventa contiguo.

Si potrebbe provare un metodo di estensione:

/// <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!

Non ho usato, ma Corde Per Java Suona intrigante. Il nome del progetto è un gioco di parole, utilizzare un corda , invece di un Stringa per un lavoro serio. Ottiene intorno alla penalizzazione delle prestazioni per prepending e altre operazioni. Vale la pena dare un'occhiata, se avete intenzione di fare un sacco di questo.

  

Una corda è un rendimento elevato   sostituzione di stringhe. Il   datastructure, descritto in dettaglio in   "Corde: un'alternativa al Strings",   fornisce asintoticamente meglio   prestazioni rispetto sia String e   StringBuffer per la stringa comune   modifiche come prepend, aggiungono,   eliminare e inserire. Come Strings,   corde sono immutabili e quindi   ben adatto per l'uso in multi-threaded   programmazione.

Si potrebbe costruire la stringa in retromarcia e poi invertire il risultato. Si incorrere una (n) Costo O invece di un O (n ^ 2) peggiore costo caso.

Ecco cosa si può fare se si vuole anteporre utilizzando la classe StringBuilder di Java:

StringBuilder str = new StringBuilder();
str.Insert(0, "text");

Se ho capito bene, il

Prova a usare Inserisci ()

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

A giudicare dalle altre osservazioni, non c'è modo rapido standard di fare questo. Utilizzando .Insert(0, "text") di StringBuilder è solo circa 1-3x più velocemente utilizzando dolorosamente lento la concatenazione di stringhe (in base a> 10000 concats), così in basso è una classe di anteporre migliaia di volte più veloce potenzialmente!

Ho incluso qualche altra funzionalità di base come ad esempio append(), subString() e length() ecc Sia accodamento e antepone variano da circa due volte più veloce a 3 volte più lento di StringBuilder aggiunge. Come StringBuilder, il buffer in questa classe aumenterà automaticamente quando il testo supera la vecchia dimensione del buffer.

Il codice è stato testato un bel po ', ma non posso garantire che è privo di bug.

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)
    }
}

Si potrebbe creare un'estensione per StringBuilder te stesso con una semplice classe:

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
    }
}

Poi, basta aggiungere:

using Application.Code.Helpers;

Per la parte superiore di qualsiasi classe che si desidera utilizzare lo StringBuilder in e ogni volta che si utilizza intelli-senso con una variabile StringBuilder, i metodi e Anteponi PrependLine apparirà. Basta ricordare che quando si utilizza Anteponi, è necessario anteporre in ordine inverso che se steste aggiungendo.

Questo dovrebbe funzionare:

aStringBuilder = "newText" + aStringBuilder; 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top