快速字符串检查查找in-string重复项

时间:2012-03-03 20:07:48

标签: c# php javascript regex

A string = "aabbccaaabbcbbdbabdaaa";
如何以有效的方式检查该字符串,找到内部字符串重复:
我的意思是:

  1. string中寻找2个字母的字符串:

    aa =“ aa bbcc aa abbcbbdbabd aa a”;
    //没有空格string这里或其他地方。只是添加它们来强调“aa” aa =“ aa bbcca aa bbcbbdbabda aa ”; 总 aa = 5;
    aa = 4,5,11,12之间的距离;
    bb =“aa bb ccaaa bb c bb dbabdaaa”;

    bb = 3;
    bb = 5,1之间的距离 ...

  2. string中查找3个字母的字符串:

    aaa =“ aaa bbcc aaa bbcbbdbabd aaa ”;;
    aaa = 3;
    aaa = 4,10之间的距离;
    ...


  3. 我的尝试是以4个循环方式进行,速度很慢。

    P.S。
    任何帮助表示赞赏。对不起我的英语不好。

    编辑:
    抱歉,这个问题很糟糕我忘了说string也应该检查4个字符重复和其他字符重复:
    aabb =“ aabb cca aabb cbbdbabdaaa”;

    aabb = 2;
    aabb = 3之间的距离;


    编辑2:
    我们要查找的重复项不应手动输入。想象一下,string是20k符号,您正在搜索 ANY 重复项(没有空格)以及这些重复项之间的距离。
    对于不正确的问题,再次感谢和抱歉。

5 个答案:

答案 0 :(得分:2)

这是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循环中移出。这样可以提高性能(特别是在找不到重复项的情况下)。

答案 1 :(得分:1)

有许多字符串搜索算法。

维基百科页面总结了它们:

http://en.wikipedia.org/wiki/String_searching_algorithm

答案 2 :(得分:1)

在使用普通字符串函数的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]);
} 

这比正则表达式更快。<​​/ p>

答案 3 :(得分:1)

这几乎就是LZW compression algorithm的作用,它只需要一次通过字符串。

答案 4 :(得分:0)

的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;
};