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