136

を使用して文字列を追加できることはわかっていますStringBuilder。文字列を先頭に追加する (つまり、文字列の前に文字列を追加する) 方法はありStringBuilderますStringBuilderか?

4

12 に答える 12

210

position パラメータを 0 に設定して insert メソッドを使用することは、先頭に追加すること (つまり、先頭に挿入すること) と同じです。

C# の例:varStringBuilder.Insert(0, "someThing");

Java の例:varStringBuilder.insert(0, "someThing");

C#Javaの両方で動作します

于 2009-04-10T21:39:16.843 に答える
34

文字列を先頭に追加するには、通常、挿入ポイントの後のすべてをバッキング配列にコピーする必要があるため、最後に追加するほど速くはありません。

ただし、Java では次のように実行できます (C# でも同じですが、メソッドは呼び出されInsertます)。

aStringBuilder.insert(0, "newText");
于 2009-04-10T21:41:13.030 に答える
12

多くのプリペンドで高いパフォーマンスが必要な場合は、独自のバージョンを作成するStringBuilder(または他のバージョンを使用する) 必要があります。標準ではStringBuilder(技術的には別の方法で実装できますが)、insert では挿入ポイントの後にデータをコピーする必要があります。n 個のテキストを挿入するには、O(n^2) 時間かかる場合があります。

単純なアプローチはchar[]、長さだけでなくバッキング バッファーにオフセットを追加することです。prepend のための十分なスペースがない場合は、厳密に必要以上にデータを上に移動します。これにより、パフォーマンスが O(n log n) に戻る可能性があります (私はそう思います)。より洗練されたアプローチは、バッファを循環させることです。このようにして、アレイの両端の予備スペースが連続します。

于 2009-04-10T22:10:34.537 に答える
7

Java の StringBuilder クラスを使用して先頭に追加する場合は、次のことができます。

StringBuilder str = new StringBuilder();
str.Insert(0, "text");
于 2009-04-10T21:39:51.693 に答える
6

文字列を逆に作成してから、結果を逆にすることができます。O(n ^ 2)の最悪の場合のコストではなく、O(n)のコストが発生します。

于 2009-04-13T16:11:16.480 に答える
6

拡張メソッドを試すことができます:

/// <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!
于 2009-04-10T21:57:08.030 に答える
4

私はそれを使用していませんが、Ropes For Java Sounds は興味をそそられます。プロジェクト名は言葉遊びです。本格的な作業にはStringの代わりにRopeを使用します。プリペンドやその他の操作のパフォーマンスの低下を回避します。これをたくさん行う場合は、一見の価値があります。

ロープはストリングの高性能代替品です。「Ropes: an Alternative to Strings」で詳細に説明されているデータ構造は、prepend、append、delete、insert などの一般的な文字列の変更に対して、String と StringBuffer の両方よりも漸近的に優れたパフォーマンスを提供します。文字列と同様に、ロープは不変であるため、マルチスレッド プログラミングでの使用に適しています。

于 2009-04-12T00:04:14.847 に答える
4

私があなたを正しく理解していれば、挿入メソッドはあなたが望むことをするように見えます. 文字列をオフセット 0 に挿入するだけです。

于 2009-04-10T21:41:47.227 に答える
3

Insert()を使用してみてください

StringBuilder MyStringBuilder = new StringBuilder("World!");
MyStringBuilder.Insert(0,"Hello "); // Hello World!
于 2009-04-10T21:40:05.217 に答える
2

他のコメントから判断すると、これを行うための標準的な迅速な方法はありません。StringBuilderの使用.Insert(0, "text")は、非常に遅い文字列連結(> 10000連結に基づく)を使用する場合の約1〜3倍の速度であるため、以下は、潜在的に数千倍速く付加するクラスです。

append()subString()などの他の基本的な機能をいくつか含めましたlength()。追加と追加の両方は、StringBuilderの追加の約2倍の速度から3倍の速度まで変化します。StringBuilderと同様に、このクラスのバッファは、テキストが古いバッファサイズをオーバーフローすると自動的に増加します。

コードはかなりテストされていますが、バグがないことを保証することはできません。

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)
    }
}
于 2011-08-17T02:34:46.513 に答える
0

これはうまくいくはずです:

aStringBuilder = "newText" + aStringBuilder; 
于 2012-08-17T15:52:22.713 に答える