代码 查找最长连续重复字符串
找出字符串中最长连续重复字符串,重复次数一样情况下,重复单元长的优先,重复单元长度一样情况下排在前面的优先,举例如下
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
public LinkedListNode
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
LinkedListNode
for (int k = 0; k < rp.ItemLen; k++)
{
startPos = rp.PosInSrc + k;
ch = s[startPos];
CharPosInfo cpInfo = table[ch];
LinkedList
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
{
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
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活动,我提交的代码(原代码速度第二,这个是事后修改了一点,比第一快乐一点)
这个问题是不是有一个后缀树的解法?
再弱弱的问一句这个Puzzle网站在公司的那个内网上?
是公司邮件组内的
有后缀树解法吗 我不知道啊。
说来听听。
这个解法比提交的最慢的代码快了1000倍。不过应该还可以更快
רҵ