寻找正确的算法来找出所有可能的二进制组合。

huangapple go评论67阅读模式
英文:

find the correct algorithme to find all the possible binary combination

问题

我正在尝试编写一个非递归的 Java 方法,名为 showStar,它接受一个字符串,并生成该字符串的所有可能组合,但不包括“*”字符。

receiving this as an input "1011*00*10",
the method `showStar` will display output like:
1011000010
1011000110
1011100010
1011100110

我尝试过这种方式,但是一旦可能的情况数量超过字符串长度,输出就不准确了。

这是我的代码。

public static void showStar(String s){
        String save;
        int count = 0;
        int poss;

        save = s.replace('*','0');
        StringBuilder myString = new StringBuilder(save);

        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '*' && myString.charAt(i) == '0') {
                myString.setCharAt(i, '1');
                System.out.println(myString);
            }
        }
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '*' && myString.charAt(i) == '1') {
                myString.setCharAt(i, '0');
                System.out.println(myString);
            }
        }
}

(代码部分未翻译)

英文:

I'm trying to write a non-recursive Java method called showStar, which takes a string, and generates ALL possible combinations of that string without the mask “*” characters.

receiving this as an input &quot;1011*00*10&quot;, 
the method `showStar` will display output like:
1011000010
1011000110
1011100010
1011100110

I tried this way, however, as soon as the number of possible cases is more than the String length, the output is not exact.

Here is my code.

public static void showStar(String s){
        String save;
        int count = 0;
        int poss;

        save = s.replace(&#39;*&#39;,&#39;0&#39;);
        StringBuilder myString = new StringBuilder(save);

        for (int i = 0; i &lt; s.length(); i++) {
            if (s.charAt(i) == &#39;*&#39; &amp;&amp; myString.charAt(i) == &#39;0&#39;) {
                myString.setCharAt(i, &#39;1&#39;);
                System.out.println(myString);
            }
        }
        for (int i = 0; i &lt; s.length(); i++) {
            if (s.charAt(i) == &#39;*&#39; &amp;&amp; myString.charAt(i) == &#39;1&#39;) {
                myString.setCharAt(i, &#39;0&#39;);
                System.out.println(myString);
            }
        }

        }

答案1

得分: 2

有k个*号。那么就有2^k种解法。您可以通过按顺序复制整数0到2^k-1的位来生成这些解法。(添加足够的前导零)

例如,1**1:

0 = 00 => 1001
1 = 01 => 1011
2 = 10 => 1101
3 = 11 => 1111
英文:

Say there are k *s. Then there are 2^k solutions. You can generate these by copying the bits from the integers 0 - 2^k-1 in order. (adding sufficient leading zeroes)

E.g. 1**1:

0 = 00 =&gt; 1001
1 = 01 =&gt; 1011
2 = 10 =&gt; 1101
3 = 11 =&gt; 1111

答案2

得分: 1

这里递归算法运行得非常完美:

  1. 通过使用 x = str.indexOf('*'); 来检查输入字符串是否包含星号 '*'。
  2. 如果没有星号出现 (x == -1),则只需打印该字符串并返回。
  3. 否则,您将星号在位置上替换为 '0' 和 '1',并为两个替换都递归调用 showStar()
public static void showStar(String str) {
    int x = str.indexOf('*');
    if(x == -1) {
        System.out.println(str);
        return;
    }
    String prefix = str.substring(0, x);
    String suffix = str.substring(x + 1);
    for (char i = '0'; i <= '1'; i++) {
        showStar(prefix + i + suffix);
    }
}

更新
在非递归实现中,我们需要收集星号的位置,然后准备二进制表示,并在已知位置设置适当的位:

public static void showStar(String str) {
    int[] xs = IntStream.range(0, str.length())
                        .filter(i -> str.charAt(i) == '*')
                        .toArray();
    int num = (int) Math.pow(2, xs.length); // 对于 n 个星号,有 2^n 种变体
    String format = xs.length > 0 ? "%" + xs.length + "s" : "%s"; // 如果没有星号,修正

    for (int i = 0; i < num; i++) {
        String bin = String.format(format, Integer.toBinaryString(i))
                           .replace(' ', '0');  // 补零
        StringBuilder sb = new StringBuilder(str);

        // 在星号的位置上设置 0 或 1
        for (int j = 0; j < xs.length; j++) {
            sb.setCharAt(xs[j], bin.charAt(j));
        }
            
        System.out.println(sb);
    }
}
英文:

Here a recursive algoritm works just perfectly:

  1. You check if an input string contains an asterisk '*' by using an x = str.indexOf(&#39;*&#39;);
  2. If no asterisk is present (x == -1), you just print the string and return
  3. Otherwise, you replace the asterisk at the position to '0' and '1' and call showStar() recursively for both replacements
public static void showStar(String str) {
    int x = str.indexOf(&#39;*&#39;);
    if(x == -1) {
        System.out.println(str);
        return;
    }
    String prefix = str.substring(0, x);
    String suffix = str.substring(x + 1);
    for (char i = &#39;0&#39;; i &lt;= &#39;1&#39;; i++) {
        showStar(prefix + i + suffix);
    }
}

Update<br/>
In non-recursive implementation we need to collect the asterisk positions, then prepare a binary representation and set appropriate bits at the known positions:

public static void showStar(String str) {
    int[] xs = IntStream.range(0, str.length())
                        .filter(i -&gt; str.charAt(i) == &#39;*&#39;)
                        .toArray();
    int num = (int) Math.pow(2, xs.length); // 2^n variants for n asterisks
    String format = xs.length &gt; 0 ? &quot;%&quot; + xs.length + &quot;s&quot; : &quot;%s&quot;; // fix if no &#39;*&#39;

    for (int i = 0; i &lt; num; i++) {
        String bin = String.format(format, Integer.toBinaryString(i))
                           .replace(&#39; &#39;, &#39;0&#39;);  // pad leading zeros
        StringBuilder sb = new StringBuilder(str);

        // set 0 or 1 in place of asterisk(s)
        for (int j = 0; j &lt; xs.length; j++) {
            sb.setCharAt(xs[j], bin.charAt(j));
        }
            
        System.out.println(sb);
    }
}

huangapple
  • 本文由 发表于 2020年9月28日 05:32:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/64093524.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定