找出字符串中最长连续重复字符串,重复次数一样情况下,重复单元长的优先,重复单元长度一样情况下排在前面的优先,举例如下
null->null
“”  -> ""
ab -> ab
aab -> a
aabbbc->b
aabbc->a
aa1212bc->12
我的代码如下,有点抽象哦
主函数入口 public string FindMostContinuouslyRepeatedString(string s)
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;

using PuzzleInterface;

namespace PuzzleSolution
{
    class CharPosInfo
    {
        public LinkedList PosList;
        public LinkedListNode CurBegNode;
        public CharPosInfo()
        {
            PosList = new LinkedList();
            CurBegNode = null; ;
        }

    };
    class CharPosTable
    {
        public CharPosInfo[] table;
        public int Count;
        public CharPosTable(string s)
        {
            table = new CharPosInfo[256];
            Count = s.Length;
            for (int i = 0; i < 256; i++)
            {
                table[(char)i] = new CharPosInfo();
            }
            char curCh;
            for (int i = 0; i < Count; i++)
            {
                curCh = s[i];
                table[curCh].PosList.AddLast(i);
            }
            for (int i = 0; i < 256; i++)
            {
                table[(char)i].CurBegNode = table[(char)i].PosList.First;
            }
        }
        public void SetRepeat(string s, ref Repeat rp,int begPos)
        {
            int startPos; int posOver,posStart;
            char ch; int v;
            LinkedListNode node;
            LinkedListNode rmNode;

            for (int k = 0; k < rp.ItemLen; k++)
            {
                 startPos = rp.PosInSrc + k;
                 ch = s[startPos];
                 CharPosInfo cpInfo = table[ch];
                 LinkedList tList = cpInfo.PosList;
     
                node = cpInfo.CurBegNode.Next.Next;
                posOver = (startPos) + rp.ItemLen * (rp.Times - 1);
                posStart=startPos + rp.ItemLen;
                while (node != null)
                {
                     v = node.Value;
                    if (v >= posOver)
                    {
                        break;
                    }
   
                    {
                        if ( v<= begPos )
                        {
                            cpInfo.CurBegNode = node;

                        }
                        if (v <= posStart)
                        {
                            node = node.Next;
                            continue;
                        }
                        rmNode = node;
                        node = node.Next;
                        tList.Remove(rmNode);

                    }

                };
            }

        }
        public int FindNextCharPos(char c, ref LinkedListNode cNode, int curPos ,int leastPos)
        {
 
            while (true)
            {
                if (cNode.Next != null)
                {
         
                    if (cNode.Next.Value <= curPos)
                    {
                        cNode = cNode.Next;
                        continue;
                    }
                    if (curPos  >leastPos)
                    {      
                        return -2;
                    }

                    return cNode.Next.Value;
                }
                else
                {
                    cNode = cNode.Next;
                    return -1;
                }
            }
        }

    }
   public  struct Repeat
    {
       public int Times;
       public int ItemLen;
       public int PosInSrc;
       public void Clear(){
           Times = 0;
           ItemLen = 0;
           PosInSrc = -1;
       }
    }

    public class Solution : IPatternRepetition
    {
        public static bool  StrEqual(string sA, int oA, string sB, int oB, int len)
        {
      
            for (int i=0; i < len; i++)
            {
                if (sA[oA + i] != sB[oB + i])
                {
                    return false;
                }
            }
            return true;

        }

        public static void GetRepeat(string s ,int sOffset, int nextOffset,ref Repeat rp)
        {
        //    Repeat rp = new Repeat();
            rp.Times = 1;
            rp.ItemLen = nextOffset - sOffset;
            rp.PosInSrc = sOffset;
            int slen = s.Length;
            int step = nextOffset;
            int stepOver =slen -rp.ItemLen;
            while (step <= stepOver)
            {
                if (StrEqual(s, sOffset, s, step, rp.ItemLen))
                {
                    rp.Times++;
                    step += rp.ItemLen;
                }
                else
                {
                    break;
                }
            }
        }
        public string FindMostContinuouslyRepeatedString(string s)
        {
            if (s == null ) return s;
            CharPosTable posTable = new CharPosTable(s);
            int slen = s.Length;
            if (slen < 2) return s;
            Repeat maxRepeat = new Repeat();
            maxRepeat.ItemLen = 1;  maxRepeat.PosInSrc = 0;  maxRepeat.Times = 1;
            char ch;
            Repeat rp = new Repeat();
            LinkedListNode cNode;
            for (int i=0; i < slen; i++)
            {
                ch = s[i];
                int curPos = i;
                cNode = posTable.table[ch].CurBegNode;
                while (cNode!=null)
                {
                    curPos = posTable.FindNextCharPos(ch, ref cNode, curPos,
                        ((slen - i) / maxRepeat.Times  + i));
                    if (curPos == -2) {
                        break;
                    }
                    rp.Clear();
                    if (curPos == -1)
                    {
                        rp.Times=1;
                        rp.ItemLen = s.Length - i;
                        rp.PosInSrc = i;
                    }
                    else
                    {
                        GetRepeat(s, i, curPos, ref rp);
                    }
                    if(rp.Times>2)  posTable.SetRepeat(s, ref rp,i);
                    if (rp.Times > maxRepeat.Times)
                    {
                        maxRepeat = rp;
                        continue;
                    }
                    if ((rp.Times == maxRepeat.Times) && (rp.ItemLen > maxRepeat.ItemLen))
                    {
                        maxRepeat = rp;
                    }
                   
                }
            }
            if (maxRepeat.PosInSrc >= 0)
            {    //    System.Console.WriteLine("Real:"+maxRepeat.Times + " " + s.Substring(maxRepeat.PosInSrc, maxRepeat.ItemLen /* maxRepeat.Times*/));
                return s.Substring(maxRepeat.PosInSrc, maxRepeat.ItemLen /* maxRepeat.Times*/);
            }
            return null;

        }
    }
}
公司内部的Puzzle活动,我提交的代码(原代码速度第二,这个是事后修改了一点,比第一快乐一点)

标签: none

暂无评论

  1. cong cong

    这个问题是不是有一个后缀树的解法?
    再弱弱的问一句这个Puzzle网站在公司的那个内网上?

    1. 是公司邮件组内的
      有后缀树解法吗 我不知道啊。
      说来听听。
      这个解法比提交的最慢的代码快了1000倍。不过应该还可以更快

    2. 13420561687 13420561687

      רҵ

    3. 15211900888 15211900888

    4. 15211929888 15211929888

添加新评论