所谓微软面试题的解答:求一个字符串中连续出现次数最多的子串

来源:互联网 发布:重庆软件行业工资 编辑:程序博客网 时间:2024/05/16 23:45

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

namespace 计算最大连续子串
{// 其实是计算出长度从1至输入字符串的长度中每种长度第一次连续出现最多的子字符串及出现次数
    class Program
    {
        static void Main(string[] args)
        {
            GetMaxSub obj = new GetMaxSub("ababcacacacacab1cb1cb1cacacabcacacakkkdkkfkkkk");
            obj.Run();
            for (int i = 1; i <= obj.source.Length; i++)
            {
                Console.WriteLine(obj.result[i] + " " + obj.time[i].ToString());
            }
            Console.WriteLine("最多的是:");
            Console.WriteLine(obj.sub + " " + obj.max.ToString());
        }
    }

    class GetMaxSub
    {
        public string source;// 要判断的字符串
        public string[] result;// 存放第一次连续出现最多的子串,子串长度就是下标
        public int[] time;// 存放第一次连续出现最多的子串出现次数

        public string sub;// 第一个最多
        public int max;// 次数

        public GetMaxSub(string v)
        {
            source = v;
            result = new string[v.Length + 1]; // 0 不用
            time = new int[v.Length + 1]; // 0 用着中间变量
        }
        public void Run()
        {
            max = 0;
            int tmp=1;
            for (int i = 1; i <= source.Length; i++)
            {// 长度从1至source.Length
                SetResult(source, i);
                if (time[i] > max)
                {
                    tmp = i;
                    max = time[i];
                }
            }
            sub = result[tmp];
        }
        void SetResult(string s, int len)
        {// 递归函数
            if (s.Length < len)
            {// 退出条件
                return;
            }

            string modle = s.Substring(0, len);  // 用作比较的子串          

            for (int i = 0; i <= s.Length - len; i += len)
            {
                string tmp = s.Substring(i, len);
                if (tmp == modle)
                {
                    time[0]++;// 相同加1
                }
                else
                {// 不同了,要比较,并切换
                    if (time[0] > time[len])
                    {// 更新len对应的子串和次数 , 如果条件改为 time[0] >= time[len] 请问实现的是什么结果??
                        time[len] = time[0];
                        result[len] = modle;
                    }
                    time[0] = 1; // 新子串已出现一次
                    modle = tmp; // 用作比较的变量更新为现在子串
                }
            }

            // 循环中最后一次切换或者根本没有切换要在此处理
            if (time[0] > time[len])
            {
                time[len] = time[0];
                result[len] = modle;
            }

            time[0] = 0; // 恢复准备递归

            if (len > 1)
            {// 等于1,不需要递归
                SetResult(s.Substring(1), len);
            }

        }     
    }
}

编程感悟:宏观上面对对象,微观上面向过程