2009-04-10 19 views
82

StringBuilderを使用して文字列を追加できることはわかっています。 StringBuilderを使用して文字列の先頭に文字列を追加する方法はありますか?StringBuilderが提供するパフォーマンス上の利点を維持できますか?C#またはJava:StringBuilderに文字列を追加しますか?

+0

質問がわかりません –

+5

前に追加します。単語は先頭にある。文字列を前置することは、一度に文字列の両端に追加するようなものでなければなりません。 –

答えて

119

positionパラメータを0に設定してinsertメソッドを使用すると、プリペンド(つまり、最初に挿入)と同じになります。

それは両方C#Java

+7

StringBuilder insert for java:http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html#insert(int,%20boolean) –

+0

関連APIの正しいJavaDocは次のとおりです。 :http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html#insert(int,%20java.lang.CharSequence%29 – ArtB

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

編集のために動作します:挿入は、いくつかのバックポイントの後にフォーマットされたコード

2

文字列を付加Insert()

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

を使用してみてくださいは、通常、すべてのものをコピーする必要がありますバッキング配列では、最後まで追加するほど速くはありません。

しかし、あなたはJavaでこのようにそれを行うことができますが(C#ではそれは同じだが、この方法はInsertと呼ばれている):

aStringBuilder.insert(0, "newText"); 
4

私が正しくあなたを理解していれば、insert methodはそれが何をやるようになります。あなたは欲しい。あなたが前に付加のたくさんの高いパフォーマンスを必要とする場合は

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

はあなたが拡張メソッドを試みることができるオフセットに文字列を挿入他の人の)。標準StringBuilder(技術的には別の方法で実装することもできますが)では、挿入ポイントの後にデータをコピーする必要があります。 n個のテキストを挿入するとO(n^2)時間かかることがあります。

単純なアプローチでは、バッファーの後ろにオフセットと長さを追加することになります。前置きのための十分な余地がない場合、厳密に必要以上にデータを上に移動します。これはパフォーマンスをO(n log n)に戻すことができます(私は思います)。より洗練されたアプローチは、バッファを周期的にすることです。このようにして、アレイの両端のスペアスペースが連続します。

10

は、あなたがStringBuilderの独自のバージョンを記述する必要があります(または使用:ちょうど0

5

私は使用していませんが、音が魅力的です。プロジェクト名は言葉遊びですが、ロープの代わりに文字列を使用してください。 prependingやその他の操作のパフォーマンスペナルティを回避します。あなたがこれをたくさんしているなら、一見有益です。

ロープは、文字列の代わりに高性能の です。 に詳細に記載 データ構造、「ロープ:文字列に代替」、 はプリペンド等 修飾は、付加 削除、挿入、共通文字列の文字列と StringBufferの両方よりも漸近的に良好 性能を提供します。文字列のように、 ロープは不変であるため、 は、マルチスレッドの プログラミングでの使用に適しています。

5

逆の文字列を作成し、その結果を逆にすることができます。 O(n^2)ワーストケースコストの代わりにO(n)コストが発生します。

+2

個人を追加する場合にのみ機能します。それ以外の場合は、追加した各文字列を逆にする必要があります。これは、文字列のサイズと数に応じて、すべての節約ではなくてもほとんどを消費します。 – ArtB

2

他のコメントから判断すると、標準的な方法はありません。 StringBuilderの.Insert(0, "text")を使用すると、痛いほど遅い文字列連結(10000以上のコンカチをベースにしています)を使用した場合の約1〜3倍の速さです。したがって、以下は、潜在的に何千倍も速くプリペンドするクラスです!

私は、,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) 
    } 
} 
0

これは動作するはずです:

aStringBuilder = "newText" + aStringBuilder; 
+0

.NETでは、これは 'string'型の値では完全に機能します。 'StringBuilder'型の値では動作しません。@ScubaSteveの答えはうまくいきます。 – Contango

1

はあなたが単純なクラスとStringBuilderをあなた自身のための拡張を作成することができます。そして、

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

、ちょうど追加:

using Application.Code.Helpers; 

あなたが使いたいクラスの先頭にStringBuilderを使用し、StringBuilder変数でintelli-senseを使用する場合は、PrependメソッドとPrependLineメソッドが表示されます。 Prependを使用する場合は、Appendingの場合とは逆の順序でPrependする必要があります。

関連する問題