string = "aabbccaaabbcbbdbabdaaa";
如何以有效的方式检出该字符串以查找内部字符串重复项:
我的意思是:
-
在
string
:
中查找两个字母的字符串aa="aabbccaaabbcbdbabdaaa"
//此处或string
中的其他位置没有空白。只是添加它们来强调"aa"
aa="aabbccaaabbcbbdbabdaaa"
总aa=5
aa之间的距离=4,5,11,12
bb="aabbccaaabbcbbdbabdaaa"
合计bb=3
bb之间的距离=5.1
… -
在
string
:
中查找3个字母的字符串aaa="aaabbccaaabbcbbdbabdaaa"
总aaa=3
aaa=4.10之间的距离
…
我的尝试是以4个循环的方式进行的,而且非常缓慢
p.S.
感谢您的帮助。对不起我的英语。
编辑:
抱歉问了个不好的问题。我忘了说string
还应该检查是否有4个字符重复和其他字符重复:
aabb="aabbccaaabbcbbdbabdaaa"
合计aabb=2
aabb=3之间的距离
第2版:
我们正在查找的重复项不应手动输入。假设string
是20k个符号,并且您正在搜索ANY重复项(没有空格)以及这些重复项之间的距离
再次感谢并抱歉问题不正确。
下面是C#中的一个解决方案
static Dictionary<string, List<int>> GetDuplicates2(string value)
{
var duplicates = new Dictionary<string, List<int>>();
for (int i = 0; i < value.Length; i++)
{
for (int slength = 2; slength < (value.Length - i) / 2 + 2; slength++)
{
var littleString = value.Substring(i, slength);
if (!duplicates.ContainsKey(littleString))
{
int nextOccurrence = value.IndexOf(littleString, i + slength - 1);
if (nextOccurrence != -1)
{
var l = new List<int>();
l.Add(i);
l.Add(nextOccurrence);
duplicates.Add(littleString, l);
while ((nextOccurrence = value.IndexOf(littleString, nextOccurrence + slength - 1)) != -1)
{
duplicates[littleString].Add(nextOccurrence);
}
}
else
{
break;
}
}
else
{
break;
}
}
}
return duplicates;
}
我是根据你的评论写的。。。
所有[2,3,…,n/2]个重复字符的列表,其中n=string长度
我认为这很有效。它返回一个Dictionary,其中包含字符串和每个重复项的索引。就性能而言,多次调用IndexOf()
可能是其中最慢的部分,但我对此一无所知。
更新我更改了代码以包含重叠要求。
更新#2我添加了两个条件,其中算法将break
从内部for
循环中移除。这大大提高了性能(尤其是在几乎找不到重复项的情况下)。
有许多字符串搜索算法。
维基百科页面很好地总结了它们:
http://en.wikipedia.org/wiki/String_searching_algorithm
在Javascript中使用普通字符串函数。
var a = " aa bbcc aa abbcbbdbabd aa a";
var s = "aa", ix = [], i=0;
while(true){
i = a.indexOf(s, i);
if(i==-1)
break;
i += s.length
ix.push(i);
}
现在ix
包含找到s
(=aa
)的索引数组。ix.length
是总发现数。下面的算法将发现两者之间的差异。
var differences=[];
for(var j=1; j<ix.length; j++){
differences.push(ix[j]-ix[j-1]);
}
这比正则表达式更快。
这几乎正是LZW压缩算法所做的,它只需要对字符串进行一次遍历。
JavaScript。
onclick = "f('a',3)" //return 2
onclick = "f('a',2)" //return 5
.......
var f = function(ch, nb){ //ch - searching character. nb - number of repetitions
var str = "aabbccaaabbcbbdbabdaaa";
var strLen = str.length;
var res = 0;
for(var i = 0; i < strLen; ++i){
if(str[i] == ch){
for(var j = i; j < nb+i || j <strLen; ++j){
if(str[j] != ch){
break;
}
if(j+1 == nb+i){
res++;
}
}
}
}
return res;
};