[英]How to count the number of all the possible binary sub strings of a given length?
[英]Count all possible decoding Combination of the given binary String in Java
假設我們有一串二進制值,其中某些部分可能對應於特定字母,例如:
A = 0
B = 00
C = 001
D = 010
E = 0010
F = 0100
G = 0110
H = 0001
例如,如果我們假設字符串"00100"
,我們可以有5
種不同的可能性:
ADA
AF
CAA
CB
EA
我必須使用動態編程提取確切數量的組合。
但是我在子問題的制定和相應的解向量的組成方面有困難。
我很欣賞正確算法公式的任何跡象。
class countString {
static int count(String a, String b, int m, int n) {
if ((m == 0 && n == 0) || n == 0)
return 1;
if (m == 0)
return 0;
if (a.charAt(m - 1) == b.charAt(n - 1))
return count(a, b, m - 1, n - 1) +
count(a, b, m - 1, n);
else
return count(a, b, m - 1, n);
}
public static void main(String[] args) {
Locale.setDefault(Locale.US);
ArrayList<String> substrings = new ArrayList<>();
substrings.add("0");
substrings.add("00");
substrings.add("001");
substrings.add("010");
substrings.add("0010");
substrings.add("0100");
substrings.add("0110");
substrings.add("0001");
if (args.length != 1) {
System.err.println("ERROR - execute with: java countString -filename- ");
System.exit(1);
}
try {
Scanner scan = new Scanner(new File(args[0])); // not important
String S = "00100";
int count = 0;
for(int i=0; i<substrings.size(); i++){
count = count + count(S,substrings.get(i),S.length(),substrings.get(i).length());
}
System.out.println(count);
} catch (FileNotFoundException e) {
System.out.println("File not found " + e);
}
}
}
本質上,動態編程是一種增強的蠻力方法。
就像在蠻力的情況下一樣,我們需要生成所有可能的結果。 但是與普通的蠻力相反,問題應該被分成更小的子問題,並且每個子問題的先前計算的結果應該被存儲和重用。
由於您使用的是遞歸,因此您需要應用所謂的記憶技術來存儲和重用中間結果。 在這種情況下, HashMap
將是存儲結果的完美手段。
但是在應用memoization以便更好地理解它之前,先從一個干凈且簡單且正常工作的遞歸解決方案開始是有意義的,然后才使用 DP 對其進行增強。
每個遞歸實現都應該包含兩個部分:
基本情況- 表示一個簡單的邊緣情況(或一組邊緣情況),其結果是預先知道的。 對於這個問題,有兩種極端情況:給定字符串的長度為0
,結果為1
(空二進制字符串""
導致空字符串""
),另一種情況是無法解碼給定的二進制字符串和結果將為0
(在下面的解決方案中,它在執行遞歸案例時自然解析)。
遞歸案例- 解決方案的一部分,其中遞歸調用和主邏輯駐留。 在遞歸的情況下,我們需要在字符串的開頭找到每個二進制“二進制字母”,然后通過傳遞子字符串(不帶“字母”)遞歸調用該方法。 這些遞歸調用的結果需要累積在從方法返回的總數中。
為了實現這個邏輯,我們只需要兩個參數:要分析的二進制字符串和二進制字母列表:
public static int count(String str, List<String> letters) {
if (str.isEmpty()) { // base case - a combination was found
return 1;
}
// recursive case
int count = 0;
for (String letter: letters) {
if (str.startsWith(letter)) {
count += count(str.substring(letter.length()), letters);
}
}
return count;
}
這個簡潔的解決方案已經能夠產生正確的結果。 現在,讓我們通過應用memoization將這個蠻力版本變成基於 DP 的解決方案。
正如我之前所說, HashMap
將是存儲中間結果的完美方法,因為它允許將計數(組合數)與特定字符串相關聯,然后幾乎立即檢索該數字(在O(1)時間內)。
它可能看起來像這樣:
public static int count(String str, List<String> letters, Map<String, Integer> vocab) {
if (str.isEmpty()) { // base case - a combination was found
return 1;
}
if (vocab.containsKey(str)) { // result was already computed and present in the map
return vocab.get(str);
}
int count = 0;
for (String letter: letters) {
if (str.startsWith(letter)) {
count += count(str.substring(letter.length()), letters, vocab);
}
}
vocab.put(str, count); // storing the total `count` into the map
return count;
}
main()
public static void main(String[] args) {
List<String> letters = List.of("0", "00", "001", "010", "0010", "0100", "0110", "0001"); // binary letters
System.out.println(count("00100", letters, new HashMap<>())); // DP
System.out.println(count("00100", letters)); // brute-force recursion
}
輸出:
5 // DP
5 // plain recursion
希望這可以幫助。 想法是使用這些值創建每個可能的字符串,並檢查input
是否以該值開頭。 如果沒有,則切換到另一個索引。
如果您准備好測試用例,您可以驗證更多。 我只測試了 2-3 個值。
public int getCombo(String[] array, int startingIndex, String val, String input) {
int count = 0;
for (int i = startingIndex; i < array.length; i++) {
String matchValue = val + array[i];
if (matchValue.length() <= input.length()) {
// if value matches then count + 1
if (matchValue.equals(input)) {
count++;
System.out.println("match Found---->" + count); //ommit this sysout , its only for testing.
return count;
} else if (input.startsWith(matchValue)) { // checking whether the input is starting with the new value
// search further combos
count += getCombo(array, 0, matchValue, input);
}
}
}
return count;
}
在主要方法中
String[] arr = substrings.toArray(new String[0]);
int count = 0;
for (int i = 0; i < arr.length; i++) {
System.out.println("index----?> " + i);
//adding this condition for single inputs i.e "0","010";
if(arr[i].equals(input))
count++;
else
count = count + getCombo(arr, 0, arr[i], input);
}
System.out.println("Final count : " + count);
我的測試結果:
input : 00100
Final count 5
input : 000
Final count 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.