How can we prepend strings with StringBuilder?

后端 未结 12 2314
一整个雨季
一整个雨季 2020-12-24 00:22

I know we can append strings using StringBuilder. Is there a way we can prepend strings (i.e. add strings in front of a string) using StringBuilder

12条回答
  •  心在旅途
    2020-12-24 00:30

    Judging from the other comments, there's no standard quick way of doing this. Using StringBuilder's .Insert(0, "text") is approximately only 1-3x as fast as using painfully slow String concatenation (based on >10000 concats), so below is a class to prepend potentially thousands of times quicker!

    I've included some other basic functionality such as append(), subString() and length() etc. Both appends and prepends vary from about twice as fast to 3x slower than StringBuilder appends. Like StringBuilder, the buffer in this class will automatically increase when the text overflows the old buffer size.

    The code has been tested quite a lot, but I can't guarantee it's free of bugs.

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

提交回复
热议问题