C# または Java:StringBuilder で文字列を先頭に追加しますか?
-
09-09-2019 - |
質問
を使用して文字列を追加できることはわかっています StringBuilder
. 。文字列を先頭に追加する方法はありますか(つまり、文字列の前に文字列を追加します) StringBuilder
パフォーマンス上の利点を維持できるため、 StringBuilder
オファー?
他のヒント
文字列を付加することは、通常、すべてをコピーする必要があります。
しかし、あなたはJavaでこのようにそれを行うことができます(C#で、それは同じですが、方法がInsert
と呼ばれている):
aStringBuilder.insert(0, "newText");
、あなたはStringBuilder
の独自のバージョンを作成する(または他の誰かのを使用)する必要があります。標準StringBuilder
(技術的には異なる方法で実装することができるが)で挿入ポイントの後のデータのコピーが必要に挿入します。テキストの挿入N片(N ^ 2)の時間がOを取ることができます。
単純なアプローチは、バッキングchar[]
バッファならびに長さにオフセットを追加することであろう。前付加のための十分なスペースがない場合には、厳密に必要以上のことにより、データを上に移動。これは、(N Nを記録)(私は思う)Oに戻ってダウンした性能をもたらすことができます。より洗練されたアプローチは、バッファサイクリックすることです。このように、アレイの両端の予備空間が連続になります。
あなたは、拡張メソッドを試すことができます:
/// <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!
私はそれを使用していないが、ロープは、Java の興味深いですね。プロジェクト名は言葉遊びで、深刻な仕事のためにのロープの代わりにの文字列のの使用。先頭追加およびその他の操作のパフォーマンスペナルティの周りを取得します。一見の価値あり、あなたはこのをたくさんやっているつもりなら。
ロープは、高性能です 弦楽のための交換。ザ・ データ構造、詳細に説明 「ロープ:文字列の代替」、 漸近的に優れてい 両方の文字列よりもパフォーマンスと 一般的な文字列のためのStringBuffer プリペンドのような変更は、追加します、 削除、および挿入します。文字列と同様に、 ロープは不変であるため、 マルチスレッドでの使用に適してい プログラミングます。
あなたは逆に文字列を作成し、その結果を逆転できます。 あなたの代わりにOのO(n)のコストが発生(N ^ 2)最悪の場合の費用ます。
ここでは、JavaのStringBuilderクラスを使用して先頭に追加したい場合は、あなたが何ができるかです。
StringBuilder str = new StringBuilder();
str.Insert(0, "text");
私が正しくあなたを理解していれば、<のhref = "http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html#insert(int,%20java。 lang.String)」のrel = 『nofollowをnoreferrer』>それはあなたが望むものをやるように見えるの方法を挿入します。ただ、オフセット0で文字列を挿入します。
挿入()の
を使用してみてくださいStringBuilder MyStringBuilder = new StringBuilder("World!");
MyStringBuilder.Insert(0,"Hello "); // Hello World!
他のコメントから判断すると、これを行うための標準的な簡単な方法はありません。 StringBuilderの.Insert(0, "text")
を使用すると、わずか約1-3Xの速そう以下、(10000 concats>に基づいて)かなり遅い文字列の連結を使用して潜在的に速く、何千回を付加するクラスです!
私は、このような追加し、前に付加両方がStringBuilderのは追加よりも遅い3倍して約2倍の高速で異なるなどappend()
、subString()
とlength()
として他のいくつかの基本的な機能を用意しました。テキストが古いバッファサイズをオーバーフローしたときの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)
}
}
あなたは単純なクラスと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の変数でインテリセンスを使用するすべての時間を使用する任意のクラスの先頭に、PrependまたはPrependLine方法が表示されます。ちょうどあなたが前に付加を使用するとき、あなたは追加はされた場合よりも、逆の順序で前に付ける必要があることを覚えています。
この作業をする必要があります:
aStringBuilder = "newText" + aStringBuilder;