C#或Java:使用StringBuilder的前面加上字符串?

问题描述 投票:91回答:12

我知道我们可以使用StringBuilder追加字符串。有没有一种方法,我们可以在前面加上字符串(即添加一个字符串的前字符串)使用StringBuilder所以我们可以保持这种StringBuilder提供的性能优势?

c# java stringbuilder
12个回答
149
投票

使用具有设置为0的位置参数插入方法将是一样预先考虑(即插入开头)。

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

这既适用C#Java


2
投票

从其他意见来看,有这样做的没有标准的快捷方式。使用StringBuilder的的.Insert(0, "text")仅约为1-3X一样快,使用十分缓慢字符串连接(基于> 10000个concats),所以下面是潜在的前面加上几千倍快的一类!

我已经包括了其他一些基本功能,如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)
    }
}

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的,你上使用Intelli-感与一个StringBuilder变量的任何时间的任何类的顶部,在前置和后置PrependLine方法会显示出来。请记住,当你使用前置,则需要以相反的顺序前面加上比如果你追加。


0
投票

这应该工作:

aStringBuilder = "newText" + aStringBuilder; 

28
投票

前面加上一个字符串,通常需要将所有内容复制将插入点向后一些支持数组在后,所以它不会像追加到年底为快。

但是你可以在Java中像下面这样做(在C#这是相同的,但该方法被称为Insert):

aStringBuilder.insert(0, "newText");

10
投票

如果你需要有很多的预规划的高性能,你需要编写自己的StringBuilder的版本(或用别人的)。随着标准StringBuilder(虽然技术上可能有不同的实现)将需要在插入点之后的数据复制。插入N片文本可以采取为O(n ^ 2)的时间。

幼稚的方法是增加一个偏移量背衬char[]缓冲器以及长度。当没有足够的空间为一个前置,通过更多的移动数据比起来是绝对必要的。这可以带来性能的回落到为O(n log n)的(我认为)。更精确的方法是使缓冲区循环。以这种方式在该阵列的两端的空余空间变得连续。


5
投票

你可以尝试扩展方法:

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

4
投票

我没有用它,但Ropes For Java听起来耐人寻味。项目名称是一个文字游戏,用它代替严肃的工作中String的绳子。获取周围的性能损失预谋和其他操作。值得一试,如果你打算做了很多本。

一根绳子是一种高性能的替代字符串。的数据结构,详细描述于“绳索:一种替代字符串”中所描述,提供了比两者字符串和StringBuffer共同串修改诸如prepend,追加,删除,和插入渐近更好的性能。像字符串,绳索是不可变的,因此非常适合于在多线程编程使用。


4
投票

你可以建立反向的字符串,然后逆转的结果。您招致的O(n)的成本,而不是为O(n ^ 2)最坏的情况下成本。


4
投票

这里是你可以做什么如果你想使用Java的StringBuilder类预先考虑:

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

3
投票

如果我理解正确的话,则insert method看起来像它会做你想要什么。只需插入字符串的偏移量为0。


2
投票

尝试使用Insert()

StringBuilder MyStringBuilder = new StringBuilder("World!");
MyStringBuilder.Insert(0,"Hello "); // Hello World!
© www.soinside.com 2019 - 2024. All rights reserved.