如何计算从列表L(所有子串的列表)

时间:2015-06-08 14:04:10

标签: algorithm

给定一个由S小写英文字母组成的字符串N

假设我们有一个列表L,包含字符串S的所有非空子串。

我需要计算从列表K中精确选择L个相等字符串的方式的数量(请注意,子字符串的长度不必等于k)。 1≤N≤5000 1≤K≤10^ 9

Exampple:

Let S=ababa. 

As List L = {"a", "b", "a", "b", "a", "ab", "ba", "ab", "ba", "aba", "bab", "aba", "abab", "baba", "ababa"}

let k=2

方式的数量为7:

("a", "a")
("a", "a") 
("a", "a") 
("b", "b") 
("ab", "ab") 
("ba", "ba") 
("aba", "aba")

类似地:

let k=3

没有办法是1:

("a", "a", "a")

5 个答案:

答案 0 :(得分:1)

“所有子串的列表”。你为什么要列出所有子串?假设你有一百万个字符的字符串,有5000亿个子字符串。所有子串的列表根本不需要解决问题。

如果K = 0则有一种方法。 如果K = 1则有N种方式。

对于k = 1到N,长度为k的每个子串可以从0到N-k的索引开始,即N-k + 1个子串。识别不同的字符串并使用哈希表计算每个字符串的数量。然后对于出现n次的每个不同的字符串,n> = k,将(n over K)加到计数中。

就是这样。

你可以通过首先查看长度为1的字符串来更快地完成它,忽略所有少于K个相等字符串的字符串,计算方法的数量,然后为每个字符串添加另一个字符并重复。假设K = 5,字符串中有一百万个字符,并且只有两个长度为6的子字符串发生了五次或更多次,那么您只需要在这两个子字符串中添加字符。

答案 1 :(得分:0)

为给定字符串构建suffix array

走遍这个数组,寻找(至少k个)邻居siffix的常见起始符号。

答案 2 :(得分:0)

以下是JavaScript中的内容:

function choose(n,k){
 if(k>n)return 0;if(k==0||n==k)return 1;var p=n;for(var i=2;i<=k;i++)p*=(n+1-i)/i;return p;
}

function f(str,k){
  var n = str.length,
      h = {},
      count = 0;

  for (var i=0; i<n; i++){
    var s = "";
    for (var j=i; k <= n - j + i && j < n; j++){
      s += str.charAt(j);
      if (h[s])
        h[s]++;
      else
        h[s] = 1;
    }
  }

  for (var i in h)
    count += choose(h[i],k);

  return count;
}

输出:

console.log(f("ababa",2));
console.log(f("ababa",3));

7
1

答案 3 :(得分:0)

正如其他人注意到的那样,你并不真正需要子串列表。因为您只关心相等的子串,所以您只需要计算子串出现的次数,并且可以使用哈希/字典/映射来跟踪它。然后,当子字符串出现k次时,精确选择n个相等子串的方法的数量是二项式系数c(n,k)。您可以为每个不同的子字符串添加所有这些二项式系数,并得到答案。

请注意,如果您要为多个k值提出此问题,则只需构建一次哈希/字典/映射。

答案 4 :(得分:-2)

如果没有关于您正在学习的语言的任何细节,我相信您可以通过一个简单的嵌套循环来实现这一目标。只需将每个值与数组或列表中的所有值进行比较。