代码改变世界

串操作

2010-12-28 21:54  Clingingboy  阅读(612)  评论(0编辑  收藏  举报

 

把其当成数组操作,只不过操作都是返回一个新的数组,而不在数组中做move操作.

代码仅供参考与练习,不保证完全正确性

基础数据结构

public class StringDs
{
    public char[] data;
    
    public char this[int index]
    {
        get { return data[index]; }
        set { data[index] = value; }
    }

    public StringDs(string str)
    {
        data = new char[str.Length];
        for (int i = 0; i < str.Length; i++)
        {
            data[i] = str[i];
        }
    }

    public StringDs(int length)
    {
        data = new char[length];
    }

    public int Length
    {
        get { return data.Length; }
    }
}

1.连接

public StringDs Concat(StringDs str)
{
    StringDs s1=new StringDs(this.Length+str.Length);
    int i = 0;
    for (i = 0; i < this.Length; i++)
    {
        s1.data[i] = this.data[i];
    }

    for (int j=0; j < str.Length; j++)
    {
        s1.data[i+j] = str.data[j];
    }
    s1.Display();
   
    return s1;
}

2.插入

public StringDs Insert(int index,string str)
{
    StringDs s1 = new StringDs(this.Length + str.Length);


    for (int i = 0; i < index; i++)
    {
        s1.data[i] = this.data[i];
    }
    int start = index;
    int len = index + str.Length;
    for (int i= start; i < len; i++)
    {
        s1.data[i] = str[i - index];
    }
    for (int i = len; i < s1.Length; i++)
    {
        s1.data[i] = this[index++];
    }
    s1.Display();
    return s1;
}

3.删除

public StringDs Remove(int index)
{
    return Remove(index, this.Length - index);
}

public StringDs Remove(int index,int length)
{
    if((index+length)>this.Length)
    {
        throw new Exception("error");
    }
    StringDs s1 = new StringDs(this.Length - length);
    for (int i = 0; i < index; i++)
    {
        s1.data[i] = this.data[i];
    }
    int start = index + length;
    for (int i = start; i < this.Length; i++)
    {
        s1.data[index++] = this.data[i];
    }
    s1.Display();
    return s1;
}

4.求字串

public StringDs SubStr(int index)
{
    return SubStr(index,this.Length-index);
}

public StringDs SubStr(int index, int len)
{
    StringDs s1 = new StringDs(len);
    for (int i = index; i < index+len; i++)
    {
        s1[i-index] = this.data[i];
    }
    s1.Display();
    return s1;
}

5.比较
(1)compare

public bool Compare(StringDs str)
{
    
    if (this.Length != str.Length)
        return false;
    for (int i = 0; i < this.Length; i++)
    {
        if (this.data[i] != str.data[i])
            return false;
    }
    return true;
}

加强:比较字符串本身,返回数字

/// <summary>
///-1 strA is less than strB.
///0  strA equals strB. 
///1  strA is greater than strB. 
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public int Compare2(StringDs str)
{
    //get less length
    int len = this.Length <= str.Length ? this.Length : str.Length;

    int i = 0;
    //compare every char
    for (i = 0; i < len; i++)
    {
        if (this.data[i] != str.data[i])
            break;
    }
    if(i<len)
    {
        //compare data structure 1<2
        if (this[i] < str[i])
            return -1;
        else
            return 1;
    }
    //compare length hello<hello1
    else if(this.Length==str.Length)
    {
        return 0;
    }
    else if (this.Length < str.Length)
    {
        return -1;
    }
    return 1;
}


(2)startwith

(3)endwith

6.定位

先找出定位的第一个字符,如果匹配的话,就继续匹配(可以从第2个开始匹配),当通过匹配后则记录该索引,并退出循环
头索引

public int Index(StringDs str)
{
    if (str.Length > this.Length)
        return -1;
    
    int len = this.Length - str.Length+1;
    int index = -1,r = 0, j = 0;
    int realIndex = -1;
    for (int i = 0; i < len; i++)
    {
        if (this.data[i] == str[0])
        {
            //find first char match
            index = i;
            
            //compare every char
            for (j = 1; j < str.Length; j++)
            {
                if(this.data[index+j]!=str.data[j])
                    break;
                else
                    r++;
            }
            //pass
            if (r==j)
            {
                realIndex = index;
                break;
            }
        }
    }
    Console.WriteLine(realIndex);
    return realIndex;
}

尾索引

从尾开始:(1.并先匹配尾字符开始)(2.先匹配尾字符,然后根据字符长度从头开始匹配)

7.统计每个字符出现的次数

若未出现过则加入数组,否则每次均要进行比较

public class Pair
{
    public Pair(char str, int count)
    {
        Char = str;
        Count = count;
    }
    
    public char Char { get; set; }

    public int Count { get; set; }
}

public List<Pair> Count()
{
    var list = new List<Pair>();
    int j = 0;
    for (int i = 0; i < this.Length; i++)
    {
        //find
        for (j = 0; j < list.Count; j++)
        {
            if (list[j].Char == this.data[i])
            {
                list[j].Count++;
                break;
            }
        }
        //not find
        if (j >(list.Count-1))
        {
            list.Add(new Pair(this.data[i], 1));
        }
    }
    foreach (var item in list)
    {
        Console.WriteLine(string.Format("{0} count:{1}",item.Char,item.Count));
    }
    return list;
}

image

8.Reverse(利用string内置的方法递归实现)

常规

public void Reverse1()
{
    var len = this.Length / 2;
    
    for (int i = 0; i < len; i++)
    {
        var obj = this.data[i];
        this.data[i] = this.data[this.Length - i - 1];
        this.data[this.Length - i - 1] = obj;
    }
    this.Display();
}

递归

            //1,2,3,4=>1 234=>1 432=>4321
            //1,2,3,4=>123 4=>321 4=>4321

两种方法都可以,利用递归思想来理解非常的容易,就是调试困难

public StringDs Reverse()
{
    var s1 = Reverse(this);
    Console.WriteLine();
    s1.Display();
    return s1;
   
}

public StringDs Reverse(StringDs s)
{
    StringDs s1, s2;
    //1,2,3,4=>1 234=>1 432=>4321
    //1,2,3,4=>123 4=>321 4=>4321

    if (s.Length > 1)
    {
        //first
        s1 = s.SubStr(0, 1);
        //reverse
        s2 = s.SubStr(1);
        s2=Reverse(s2);
        //concat
        return s2.Concat(s1);
    }

    //if (s.Length > 1)
    //{
    //    //reverse
    //    s1 = s.SubStr(0, s.Length-1);
    //    //last
    //    s2 = s.SubStr(s.Length - 1);
    //    s1=Reverse(s1);
    //    //concat
    //    return s2.Concat(s1);
    //}
    return s;
}

9.用递归判断某个字符是否在串中

利用Substr,每查找一次则减少一个字符,若串中的第一个字符匹配或者串长度为0则退出1

public bool Find(char str)
{
    return Find(this, str);
}

public bool Find(StringDs s,char str)
{
    StringDs s1=null;
    //quit
    if (s.Length == 0)
        return false;
    else if (s.data[0] == str)
        return true;
    else
    {
        //continue
        s1 = s.SubStr(1);
        return s1.Find(str);
    }
}

image

10.用指定字符串替换指定索引和长度的字符

删除指定长度字符,并用另一个字符串替换

即复制三次,复制索引值之前的字符,复制要替换的字符,复制索引加上长度之后的字符

public StringDs RepStr(int index, int len, string str)
{
    StringDs s1 = new StringDs(this.Length + str.Length - len);
    //copy original
    for (int i = 0; i < index; i++)
    {
        s1.data[i] = this.data[i];
    }
   
    //copy str
    for (int i = 0; i < str.Length; i++)
    {
        s1.data[index+i] = str[i];
    }

    //copy last str
    //start index str.Length-len
    for (int i = index+len; i < this.Length; i++)
    {
        s1.data[str.Length-len+i] = this.data[i];
    }
    s1.Display();
    return s1;
}

 

StringDs s1 = new StringDs("hello");
s1.RepStr(1, 1, "aaaaaa");

image

 

二.链串实现

可能判断加的不多,仅供参考,不保证完全的准确性

public class StringNodeDs
{
    public char data;
    public StringNodeDs next;

    public StringNodeDs()
    {
    }

    public StringNodeDs(string str)
    {
        var node = this;
        for (int i = 0; i < str.Length; i++)
        {
            node.data = str[i];
            if (str.Length-i>1)
            {
                node.next = new StringNodeDs();
                node = node.next;
            }
        }
    }

    public StringNodeDs(StringNodeDs str)
    {
        var node = str;
        var currentNode = this;
        while (node != null)
        {
            currentNode.data = node.data;
            if (node.next!=null)
            {
            currentNode.next = new StringNodeDs();
            currentNode = currentNode.next;
            }
            node = node.next;
        }
    }

    public int GetLength()
    {
        var node = this;
        int i = 0;
        while (node != null)
        {
            node = node.next;
            i++;
        }
        return i;
    }

    public void Display()
    {
        var node = this;
        while (node!=null)
        {
            Console.Write(node.data);
            node = node.next;
        }
        Console.WriteLine();
    }

    public StringNodeDs GetLast()
    {
        var node = this;
        while (node.next != null)
        {
            node = node.next;
        }
        return node;
    }

    public StringNodeDs Concat(StringNodeDs str)
    {
        var node = GetLast();
        node.next = str;
        this.Display();
        return this;
    }

    public StringNodeDs Concat1(StringNodeDs str)
    {
        StringNodeDs s1 = new StringNodeDs(this);
        var node = s1.GetLast();
        node.next = str;
        s1.Display();
        return node;
    }

    public StringNodeDs Remove(int index)
    {
        return Remove(index, this.GetLength() - index);
    }

    public StringNodeDs Remove(int index, int length)
    {
        if ((index + length) > this.GetLength())
        {
            throw new Exception("error");
        }

        StringNodeDs s1 = new StringNodeDs();
        var currentNode = s1;
        var node = this;
        int i = 0;
        while (i < (index + length))
        {
            if (i < index)
            {
                currentNode.data = node.data;

                if (index-i>1)
                {
                    currentNode.next = new StringNodeDs();
                    currentNode = currentNode.next;
                }
            }
            node = node.next;
            i++;
        }
        s1.Concat(node);
        return s1;
    }

    private StringNodeDs AddData(char data)
    {
        this.data = data;
        this.next=new StringNodeDs();
        return this.next;
    }

    public StringNodeDs Insert(int index, StringNodeDs str)
    {
        StringNodeDs s1 = new StringNodeDs();
        var node = this;
        var currentNode = s1;

        for (int i = 0; i < index; i++)
        {
            currentNode = currentNode.AddData(node.data);
            node = node.next;
        }
        StringNodeDs next=null;
        if (node!=null)
        {
            next = new StringNodeDs(node);
        }
        node = str;
        while (node!=null)
        {
            currentNode = currentNode.AddData(node.data);
            node = node.next;
        }
        currentNode.next = next;
        s1.Display();
        return s1;
    }

    public int Compare(StringNodeDs str)
    {
        var first = this;
        var second = str;
        
        //compare
        while (first!=null && second!=null)
        {
            
            if (first.data==second.data)
            {
                first = first.next;
                second = second.next;
            }
            else
                break;
        }

        if (first!=null && second!=null)
        {
            //compare data structure 1<2
            if (first.data < second.data)
                return -1;
            else
                return 1;
        }

        while (first != null && second != null)
        {
            first = first.next;
            second = second.next;
        }
        //equal length
        if (first==null && second==null)
            return 0;
        //first length>second length
        if(first != null)
            return 1;
        return -1;
    }

    public int Index(StringNodeDs str)
    {
        var node = this;
        int index = 0;
        int r = 0, j = 0;
        int realIndex = -1;
        while (node!=null)
        {
            if (node.data.Equals(str.data))
            {
                var strNode = str;
                var internalNode = node;
                j = 0;
                r = 0;
                while (strNode != null && internalNode!=null)
                {
                    j++;
                    if (!internalNode.data.Equals(strNode.data))
                        break;
                    else
                        r++;
                    internalNode = internalNode.next;
                    strNode = strNode.next;
                }
                //pass
                if (r == j)
                {
                    realIndex = index;
                    break;
                }
            }
            index++;
            node = node.next;
        }
        Console.WriteLine(realIndex);
        return realIndex;
    }

    public StringNodeDs SubStr(int index)
    {
        return SubStr(index, 0);
    }

    public StringNodeDs SubStr(int index, int len)
    {
        int i = 0;
        var node = this;
        var end = index + len;
        StringNodeDs s1 = new StringNodeDs();
        var currentNode = s1;
        while (node!=null)
        {
            if ((i >= index && i < end) || (i >= index &&len == 0))
            {
                currentNode = currentNode.AddData(node.data);
            }
            node = node.next;
            i++;
        }
        s1.Display();
        return s1;
    }

}

扩展方法

1.删除指定长度字符,并用另一个字符串替换(同上第10点)

public StringNodeDs RepStr(int index, int len, string str)
{
    StringNodeDs s1 = new StringNodeDs();
    var node = this;
    var currentNode = s1;

    //copy original
    for (int i = 0; i < index; i++)
    {
        currentNode = currentNode.AddData(node.data);
        node = node.next;
    }
    var lastStartNode = node;
    for (int i = 0; i < len; i++)
    {
        lastStartNode = lastStartNode.next;
    }
    //copy str
    StringNodeDs prev = currentNode; 
    for (int i = 0; i < str.Length; i++)
    {
        prev = currentNode;
        currentNode = currentNode.AddData(str[i]);
    }
    //copy last str
    while (lastStartNode != null)
    {
        prev.next = new StringNodeDs();
        prev.next.data = lastStartNode.data;
        lastStartNode = lastStartNode.next;
    }
   
    s1.Display();
    return s1;
}

2.删除串中所有的字串xxxx

public StringNodeDs DeleteSub(StringNodeDs str)
{
    StringNodeDs s1 = new StringNodeDs();
    var currentNode = s1;
    var node = this;
    int r = 0, j = 0;
    while (node != null)
    {
        if (node.data.Equals(str.data))
        {
            var strNode = str;
            var internalNode = node;
            j = 0;
            r = 0;
            while (strNode != null && internalNode != null)
            {
                j++;
                if (!internalNode.data.Equals(strNode.data))
                    break;
                else
                    r++;
                internalNode = internalNode.next;
                strNode = strNode.next;
            }
            //pass
            if (r == j)
                node = internalNode;
            else
                node = node.next;
        }
        else
        {
            currentNode.data = node.data;
            if (node.next != null)
            {
                currentNode.next = new StringNodeDs();
                currentNode = currentNode.next;
            }
            node = node.next;
        }
        
    }
    s1.Display();
    return s1;
}

3.判断链串是否递增排列

public bool IsIncrease()
{
    var node = this;
    while (node.next!=null)
    {
        if (node.data >= node.next.data)
            return false;
        node = node.next;
    }
    return true;
}

算是结束了…