簡體   English   中英

如何計算從列表L(所有子串的列表)中選擇k個相等子串的方式的數量

[英]How to count the number of ways of choosing of k equal substrings from a List L(the list of All Substrings)

給定由N個小寫英文字母組成的字符串S

假設我們有一個列表L ,該列表L由字符串S的所有非空子字符串組成。

我需要計算從列表L完全選擇K相等字符串的方法的數量(請注意,子字符串的長度不必等於k )。 1≤N≤5000 1≤K≤10 ^ 9

范例:

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")

“所有子字符串的列表”。 為什么會有所有子串的列表? 假設您有一百萬個字符的字符串,其中有五千億個子字符串。 解決問題根本不需要所有子字符串的列表。

如果K = 0,則只有一種方法。 如果K = 1,則有N種方法。

對於k = 1到N,每個長度為k的子串可以從0到N-k的索引處開始,即N-k +1個子串。 使用哈希表確定不同的字符串並計算每個字符串有多少個。 然后對於出現n次的每個不同字符串,n> = k,將(n乘以K)添加到您的計數中。

而已。

通過先查看長度為1的字符串,忽略所有少於K個相等字符串的字符串,計算方式數,然后向每個方式添加另一個字符並重復,可以更快地做到這一點。 假設K = 5,您在字符串中有一百萬個字符,並且只有兩個長度為6的子字符串出現了五次或更多次,那么您只需要向這兩個子字符串中添加字符。

為給定的字符串構建后綴數組

遍歷此數組,查找(至少k個)鄰居后綴的常見起始符號。

這是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

正如其他人所注意到的,您實際上並不需要子字符串列表。 因為您只關心相等的子字符串,所以您只需要計算一個子字符串出現的次數,就可以使用哈希/字典/映射進行跟蹤。 那么,當子串出現n次時,選擇恰好k相等的子串的方法的數量就是二項式系數c(n,k) 您可以為每個不同的子字符串加總所有這些二項式系數,然后您便有了答案。

請注意,如果您向這個問題詢問多個k值,則只需構建一次哈希/字典/映射。

沒有關於您正在學習的語言的任何詳細信息,我相信您可以通過一個簡單的嵌套循環來完成。 只需將每個值與數組或列表中的所有值進行比較即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM