[英]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.