我知道我们可以使用StringBuilder
附加字符串。有没有一种方法可以使用StringBuilder
预先安装字符串(即在字符串前添加字符串),以便我们可以保持StringBuilder
提供的性能优势?C#或Java:用StringBuilder预加字符串?
回答
针对java的StringBuilder插入:http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html#insert(int,%20boolean) – 2009-04-12 16:21:41
相关API的正确JavaDoc是:http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html#insert(int,%20java.lang.CharSequence%29 – ArtB 2012-02-28 19:12:14
StringBuilder str = new StringBuilder();
str.Insert(0, "text");
编辑:格式化代码
尝试使用Insert()
StringBuilder MyStringBuilder = new StringBuilder("World!");
MyStringBuilder.Insert(0,"Hello "); // Hello World!
前面加上一个字符串,通常需要将所有内容复制将插入点向后一些后在后备数组中,所以它不会像追加到最后一样快。
但是你可以在Java中像下面这样做(在C#这是相同的,但该方法被称为Insert
):
aStringBuilder.insert(0, "newText");
如果我理解正确的话,则insert method看起来像它会做什么你要。只需插入串在偏移0
你可以尝试扩展方法:
/// <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!
如果你需要有大量的预规划的高性能,你需要编写自己的StringBuilder
版本(或使用别人的)。使用标准StringBuilder
(虽然在技术上可以以不同的方式实现)插入要求在插入点之后复制数据。插入n段文字可能需要O(n^2)次。
一个简单的方法是在后备char[]
缓冲区中添加一个偏移量以及长度。如果没有足够的空间进行预设,请将数据向上移动超过绝对必要的数量。这可以使性能回到O(n log n)(我认为)。更精细的方法是使缓冲区循环。这样阵列两端的备用空间变得连续。
我没有使用它,但Ropes For Java听起来有趣。该项目的名称是一个玩的话,使用绳而不是字符串认真的工作。获取前置和其他操作的性能损失。值得一看,如果你将要做很多这样的事情。
一根绳子是高性能 替代字符串。的数据结构 ,中详细描述 “绳索:一种替代字符串”, 提供比字符串和 StringBuffer的渐近更好 性能以便共同串 修改诸如prepend,追加,删除 ,并插入。像字符串一样, 绳索是不可变的,因此 非常适合用于多线程 编程。
您可以反向构建字符串,然后反转结果。 您将承担O(n)成本,而不是O(n^2)最差成本。
这只适用于如果你追加个人字符,否则你需要将每个字符串反过来,如果不是所有的节省量,都会根据字符串的大小和数量来消耗大部分存储空间。 – ArtB 2012-04-26 18:10:31
从其他评论来看,没有标准的快速方法来做到这一点。使用StringBuilder的.Insert(0, "text")
大约只有使用痛苦的慢字符串连接(基于> 10000连接)的速度快1-3倍,所以下面是一个类,可能需要数千次更快!
我已经包括了其他一些基本功能,如append()
,subString()
和length()
等等都附加,并预置约两倍的速度变化3倍慢于StringBuilder的追加。像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)
}
}
这应该工作:
aStringBuilder = "newText" + aStringBuilder;
在.NET中,这与'string'类型的值完全匹配,但不适用于StringBuilder类型的值。@ScubaSteve的答案很好。 – Contango 2014-10-03 12:22:34
你可以创建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变量的SenseBuilder,Prepend和PrependLine方法都会显示出来。请记住,当您使用“前置”时,您需要按照与“正在追加”相反的顺序进行预置。
- 1. Java StringBuilder附加长字符串错误
- 2. Java StringBuilder不会附加字符串
- 3. 字符串StringBuilder的C#
- 4. 使用StringBuilder的JAVA字符串反转
- 5. 使用StringBuilder追加字符串
- 6. 用StringBuilder替换字符串?
- 7. 追加字符串直接或使用StringBuilder
- 8. StringBuilder子字符串和反向 - Java
- 9. 在字符串和/或StringBuilder中使用控制字符(\ x1f)
- 10. 的Java的StringBuilder - 追加字符
- 11. StringBuilder附加字符串中断UTF 8
- 12. LINQ从字符串追加到StringBuilder []
- 13. StringBuilder不能附加字符串
- 14. 删除附加字符串到StringBuilder
- 15. StringBuilder字符串格式
- 16. 将C#StringBuilder /字符串传递给C++ char *使用DLL
- 17. 在C#中包含空字符StringBuilder字符串
- 18. 在Java或C中匹配字符串#
- 19. StringBuilder错误 - 字符串未被占用
- 20. 凡用StringBuffer/StringBuilder的非字符串
- 21. 字符串比StringBuilder更有用吗?
- 22. 串联字符的字符串 - 使用的StringBuilder的append()
- 23. .NET StringBuilder和逐字字符串文字
- 24. Android SAX的XML解析器与字符串或Stringbuilder或Stringbuffer
- 25. 什么使用字符串或StringBuilder保持大文本?
- 26. Android StringBuilder与字符串串联
- 27. Java字符串操作 - 添加空格或子字符串
- 28. Java - 多少个字符串concat应该提示使用StringBuilder?
- 29. 如何在Java中使用StringBuilder在两个字符串之间添加空格?
- 30. 在C中使用stringbuilder处理巨大的字符串#
我不明白你的问题 – 2009-04-10 21:41:45
Prepend。这个词是prepend。预先出现的字符串必须是一次性添加到字符串的两端,我猜? – 2009-04-11 23:38:38