hi,it's onebird‘s blog。My homepage is onebird.net.
onebird | 26 六月, 2008 05:52
找出字符串中最长连续重复字符串,重复次数一样情况下,重复单元长的优先,重复单元长度一样情况下排在前面的优先,举例如下
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<int> PosList;
public LinkedListNode<int> CurBegNode;
public CharPosInfo()
{
PosList = new LinkedList<int>();
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<int> node;
LinkedListNode<int> rmNode;
for (int k = 0; k < rp.ItemLen; k++)
{
startPos = rp.PosInSrc + k;
ch = s[startPos];
CharPosInfo cpInfo = table[ch];
LinkedList<int> 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<int> 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<int> 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活动,我提交的代码(原代码速度第二,这个是事后修改了一点,比第一快乐一点)
onebird | 26/06/2008, 22:39
是公司邮件组内的
有后缀树解法吗 我不知道啊。
说来听听。
这个解法比提交的最慢的代码快了1000倍。不过应该还可以更快
福建 龙岩 永定 南开 酷讯 微软 搜索 广告 推荐 IM 网络应用 技术研发,工程管理 音乐 旅游 IPhone
| « | 六月 2008 | » | ||||
|---|---|---|---|---|---|---|
| 一 | 二 | 三 | 四 | 五 | 六 | 日 |
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | ||||||
Re: 代码 查找最长连续重复字符串
cong | 26/06/2008, 16:44
这个问题是不是有一个后缀树的解法?
再弱弱的问一句这个Puzzle网站在公司的那个内网上?