C#数据结构-string字符串实现

using System;
using System.Collections;
using System.Collections.Generic;

namespace StructScript
{
    public sealed class StringScript : IEnumerable<char>, IEnumerable, IEquatable<StringScript>
    {
        private int mLength = 0;
        private char[] mItems;
        private static readonly char[] mEmptyArr = new char[0];
        public static readonly StringScript Empty = new StringScript(mEmptyArr);

        public StringScript(char[] value)
        {
            if (value != null)
            {
                int length = value.Length;
                if (length == 0)
                {
                    mItems = mEmptyArr;
                }
                else
                {
                    mItems = new char[length];
                    for (int i = 0; i < length; i++)
                    {
                        mItems[i] = value[i];
                    }
                    mLength = length;
                }
            }
        }

        public char this[int index]
        {
            get
            {
                if (index >= mLength || index < 0)
                {
                    throw new IndexOutOfRangeException();
                }
                return mItems[index];
            }
            set
            {
                if (index >= mLength || index < 0)
                {
                    throw new IndexOutOfRangeException();
                }
                mItems[index] = value;
            }
        }

        public int Length
        {
            get
            {
                return mLength;
            }
        }

        public bool Equals(StringScript other)
        {
            if (this == null)
            {
                throw new ArgumentNullException();
            }
            if (other == null)
            {
                return false;
            }
            if (this.Length != other.Length)
            {
                return false;
            }
            if (Equals(this, other))
            {
                return true;
            }
            return false;
        }

        public static bool Equals(StringScript strA, StringScript strB)
        {
            int length = strA.Length;
            bool isEqual = true;
            for (int i = 0; i < length; i++)
            {
                if (strA[i] != strB[i])
                {
                    isEqual = false;
                }
            }
            if (isEqual)
            {
                return true;
            }
            return false;
        }

        public bool Contains(StringScript value)
        {
            int index;
            return Contain(value, out index);
        }

        private bool Contain(StringScript value, out int index, int startIndex = 0)
        {
            index = 0;
            if (value == null)
            {
                throw new ArgumentNullException();
            }
            int length = value.Length;
            // mLength - length - startIndex比较的次数
            for (int i = startIndex; i < mLength - length - startIndex; i++)
            {
                bool isEqual = true;
                // 从索引0开始,遍历长度value.Length的数据,查找匹配的字符
                for (int j = i; j < length + i; j++)
                {
                    // j - i 保持需要比较的字符串的索引从0开始
                    if (mItems[j] != value[j - i])
                    {
                        isEqual = false;
                    }
                }
                if (isEqual)
                {
                    index = i;
                    return true;
                }
                else
                {
                    continue;
                }
            }
            return false;
        }

        public StringScript Replace(StringScript oldValue, StringScript newValue)
        {
            if (oldValue == null)
            {
                throw new ArgumentNullException();
            }
            if(oldValue.Length > mLength)
            {
                return this;
            }
            char[] dataSource = new char[mLength];
            char[] dataOld = new char[oldValue.Length];
            char[] dataNew = new char[newValue.Length];
            for (int i = 0; i < mLength; i++)
            {
                dataSource[i] = mItems[i];
            }
            for (int i = 0; i < dataOld.Length; i++)
            {
                dataOld[i] = oldValue[i];
            }
            for (int i = 0; i < dataNew.Length; i++)
            {
                dataNew[i] = newValue[i];
            }
            List<char> newCharList = new List<char>();
            for (int i = 0; i < dataSource.Length; i++)
            {
                //找到与被替换数据第一个
                if (dataSource[i] == dataOld[0])
                {
                    //标志当前的i位置是不是要替换的位置
                    bool IsReplace = false;
                    //遍历被替换的数据
                    for (int j = 0; j < dataOld.Length; j++)
                    {
                        // dataOld需要替换的字符串长度 + 第一个匹配的替换索引,应该不超过原数据的长度
                        if (((i + j) < dataSource.Length) && (dataSource[i + j] == dataOld[j]))
                        {
                            IsReplace = true;
                        }
                        else
                        {
                            IsReplace = false;
                            break;
                        }
                    }
                    if (IsReplace)
                    {
                        //当前位置要加上被替换的数据的长度,不然只是替换了要被替换的数据的第一个char字符
                        i += dataOld.Length - 1;
                        //遍历你替换后的数据,添加到List里面
                        for (int k = 0; k < dataNew.Length; k++)
                        {
                            newCharList.Add(dataNew[k]);
                        }
                    }
                    else
                    {
                        //添加原数据的char[i]位置的字符
                        newCharList.Add(dataSource[i]);
                    }
                }
                else
                {
                    //添加原数据的char[i]位置的字符
                    newCharList.Add(dataSource[i]);
                }
            }
            return new string(newCharList.ToArray());
        }

        public bool EndsWith(StringScript value)
        {
            int length = value.Length;
            bool isEqual = true;
            for (int i = length - 1; i > 0; i--)
            {
                if (mItems[i] != value[i])
                {
                    isEqual = false;
                }
            }
            if (isEqual)
            {
                return true;
            }
            return false;
        }

        public bool StartsWith(StringScript value)
        {
            return Equals(value, this);
        }

        public int IndexOf(StringScript value)
        {
            int index;
            if (Contain(value, out index))
            {
                return index;
            }
            return -1;
        }

        public int IndexOf(StringScript value, int startIndex)
        {
            int index;
            if (Contain(value, out index, startIndex + 1))
            {
                return index;
            }
            return -1;
        }

        public StringScript[] Split(params char[] separator)
        {
            if (separator == null)
            {
                throw new ArgumentNullException();
            }
            //记录字符串中的分隔符总数和分隔符所在位置索引
            int[] numArr = new int[mLength];
            //分隔符的计数
            int num = 0;
            int length = separator.Length;
            for (int j = 0; j < mLength; j++)
            {
                for (int i = 0; i < length; i++)
                {
                    char item = separator[i];
                    if (mItems[j] == item)
                    {
                        numArr[num] = j;
                        num++;
                        break;
                    }
                }
            }
            if (num == 0)
            {
                StringScript[] script = new StringScript[1];
                script[0] = this;
                return script;
            }
            //String的数组总数
            int count = num + 1;
            //每次子字符串截取开始的索引
            int index = 0;
            StringScript[] items = new StringScript[count];
            for (int i = 0; i < count; i++)
            {
                StringScript str = null;
                if (i == count - 1)
                {
                    str = Substring(index, mLength - index);
                }
                else
                {
                    str = Substring(index, numArr[i] - index);
                }
                // 当分隔符在索引为0或者mLength - 1时,截取的子字符串为空,不赋值给items数组
                if (str != null)
                {
                    items[i] = str;
                }
                index = numArr[i] + 1;
            }
            return items;
        }

        /// <summary>
        /// 子字符串从指定的字符位置开始且具有指定的长度
        /// </summary>
        public StringScript Substring(int startIndex, int length)
        {
            if (startIndex + length > mLength || startIndex > mLength || length > mLength || startIndex < 0 || length < 0)
            {
                throw new IndexOutOfRangeException();
            }
            if (length == 0)
            {
                return null;
            }
            char[] items = new char[length];
            for (int i = startIndex; i < startIndex + length; i++)
            {
                // i - startIndex 保持items数组的索引从0开始
                items[i - startIndex] = mItems[i];
            }
            StringScript script = new StringScript(items);
            return script;
        }

        /// <summary>
        /// 转换为大写
        /// 第一种实现方式,判断是否是大写,否,进行转换,mItems[i] - 32
        /// 第二种实现方式,不用判断是否大小写,通过二进制转换 & 0101 1111,但C#中的& 默认操作的是十进制的数字
        /// 所以需要转换成十进制95,或者十六进制0x5F
        /// 原因,大小写字母在二进制上,只有第六个位置的值有不同(从右开始数)实际差10 0000 也就是32,实际为7位,这里前面添0方便比较
        /// a 的2进制: 0110 0001 ascil: 97
        /// A 的2进制: 0100 0001 ascil: 65
        /// </summary>
        /// <returns></returns>
        public StringScript ToUpper()
        {
            char[] items = new char[mLength];
            for (int i = 0; i < mLength; i++)
            {
                items[i] = (char)(mItems[i] & 0x5F);
            }
            return new StringScript(items);
        }

        /// <summary>
        /// 转换为小写
        /// 第一种实现方式,判断是否是小写,否,进行转换,mItems[i] + 32
        /// 第二种实现方式,不用判断是否大小写,通过二进制转换 | 0010 0000,但C#中的& 默认操作的是十进制的数字
        /// 所以需要转换成十进制32,或者十六进制0x20
        /// 原因,大小写字母在二进制上,只有第六个位置的值有不同(从右开始数)实际差10 0000 也就是32,实际为7位,这里前面添0方便比较
        /// a 的2进制: 0110 0001 ascil: 97
        /// A 的2进制: 0100 0001 ascil: 65
        /// </summary>
        /// <returns></returns>
        public StringScript ToLower()
        {
            char[] items = new char[mLength];
            for (int i = 0; i < mLength; i++)
            {
                items[i] = (char)(mItems[i] | 0x20);
            }
            return new StringScript(items);
        }

        public IEnumerator<char> GetEnumerator()
        {
            return new Enumerator(this);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new Enumerator(this);
        }

        public struct Enumerator : IEnumerator<char>
        {
            private StringScript list;
            private int index;
            private char current;

            public Enumerator(StringScript list)
            {
                this.list = list;
                index = 0;
                current = default(char);
            }

            public char Current
            {
                get
                {
                    if (index <= 0 || index > list.Length)
                    {
                        throw new IndexOutOfRangeException();
                    }
                    return current;
                }
            }

            object IEnumerator.Current
            {
                get
                {
                    if (index <= 0 || index > list.Length)
                    {
                        throw new IndexOutOfRangeException();
                    }
                    return current;
                }
            }

            public void Dispose()
            {

            }

            public bool MoveNext()
            {
                if (index >= 0 && index < list.Length)
                {
                    current = list[index];
                    index++;
                    return true;
                }
                return false;
            }

            public void Reset()
            {
                index = 0;
                current = default(char);
            }
        }

        public static implicit operator StringScript(string v)
        {
            if (v != null)
            {
                int length = v.Length;
                if (length == 0)
                {
                    return Empty;
                }
                else
                {
                    char[] items = new char[length];
                    for (int i = 0; i < length; i++)
                    {
                        items[i] = v[i];
                    }
                    StringScript script = new StringScript(items);
                    return script;
                }
            }
            return null;
        }

        public override string ToString()
        {
            return new string(mItems);
        }

    }
}

附上,测试用例:

using System;

namespace StructScript
{
    class TestString
    {
        static void Main(string[] args)
        {
            StringScript string1a = "This is a StringScript created by assignment.";
            Console.WriteLine(string1a.ToString());
            Show(string1a);
            StringScript string1a1 = "";
            Show(string1a1);

            StringScript string2a = "The path is C:\\PublicDocuments\\Report1.doc";
            Show(string2a);
            StringScript string3a = @"The path is C:\PublicDocuments\Report1.doc";
            Show(string3a);

            char[] chars = { 'w', 'o', 'r', 'd' };
            StringScript string1 = new StringScript(chars);
            Show(string1);

            连接字符串
            StringScript string2b = "This is one sentence. " + "This is a second. ";
            string2b += "This is a third sentence.";
            Show(string2b);

            IndexOf Substring截取字符串
            StringScript sentence = "This sentence has five words.";
            // Extract the second word.
            int startPosition = sentence.IndexOf(" ") + 1;
            StringScript word2 = sentence.Substring(startPosition, sentence.IndexOf(" ", startPosition) - startPosition);
            Console.WriteLine("Second word: " + word2);

            EndsWith StartsWith
            String[] strings = { "This is a string.", "Hello!", "Nothing.",
                           "Yes.", "randomize" };
            foreach (var value in strings)
            {
                bool endsInPeriod = value.EndsWith(".");
                bool startInPeriod = value.StartsWith("Th");
                Console.WriteLine("'{0}' ends in a period: {1}",
                                  value, endsInPeriod);
                Console.WriteLine("'{0}' start in a period: {1}",
                                  value, startInPeriod);
            }

            //split
            String str = "sThis is a short string.s";
            Char delimiter = 's';
            String[] substrings = str.Split(delimiter);
            foreach (var substring in substrings)
                Console.WriteLine(substring);


            replace
            StringScript aaa = "The initial string";
            aaa = aaa.Replace("i", "out");
            Show(aaa);

            //equals 大小写
            Console.OutputEncoding = System.Text.Encoding.UTF8;
            StringScript word = "File";
            StringScript[] others = { word.ToLower(), word, word.ToUpper(), "fıle" };
            foreach (var other in others)
            {
                if (word.Equals(other))
                    Console.WriteLine("{0} = {1}", word, other);
                else
                    Console.WriteLine("{0} {1} {2}", word, '\u2260', other);
            }

            Console.ReadLine();
        }

        private static void Show(StringScript str)
        {
            if (str != null)
            {
                int length = str.Length;
                for (int i = 0; i < length; i++)
                {
                    Console.Write(str[i]);
                }
                Console.WriteLine();
            }
        }
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值