简体   繁体   English

Java,数组组合算法

[英]Java, combination algorithm with arrays

I am trying to implement an algorithm to calculate all combinations of an Array where one character is replaced by '*' without changing the order of the Arrays entries. 我正在尝试实现一种算法来计算Array的所有组合,其中一个字符由'*'替换,而不更改Arrays条目的顺序。

For example the following Array with two entries: 例如,以下带有两个条目的数组:

{"A", "B"} {“ A”,“ B”}

Should reproduce this Output: 应重现此输出:

[A, B]
[*, B]
[A, *]
[*, *]

My current code is: 我当前的代码是:

public class TestCombination {

   public static void combinations(List<String[]> values, String[] attr, String all, int iteration) {
      String[] val = new String[attr.length];
      for (int i = 0; i < attr.length; i++) {
         val[i] = attr[i];
      }
      if (iteration < attr.length) {
         val[iteration] = all;
      }

      values.add(val);
      iteration = iteration + 1;

      if (Math.pow(attr.length, 2) != iteration) {
         combinations(values, attr, all, iteration);
      }
   }

   public static void main() {
      String[] values = new String[] {"A", "B"};
      List<String[]> resultValues = new ArrayList<String[]>();
      combinations(resultValues, values, "*", 0);

      for (String[] res : resultValues) {
         System.out.println(Arrays.deepToString(res));
      }
   }

}

The Output i get is: 我得到的输出是:

[*, B]
[A, *]
[A, B]
[A, B]

This is especially because of this not correct code: 这尤其是因为此不正确的代码:

if (iteration < attr.length) {
    val[iteration] = all;
}

I do not have any idea, how the next possible index can be calculated to replace the Array value at that index by '*'. 我不知道如何计算下一个可能的索引,以用“ *”替换该索引处的Array值。

Can you give me please some hints on that? 你能给我一些提示吗?

One simple approach is to use a bit mask of length n . 一种简单的方法是使用长度为n的位掩码。 Iterate all n-digit binary numbers, and then for each of the n positions do the following: 迭代所有n位二进制数,然后对n位置中的每个位置执行以下操作:

  • If position i has one, output an asterisk * 如果位置i有一个,则输出一个星号*
  • If position i has zero, output the original value. 如果位置i为零,则输出原始值。

This will cover all combinations. 这将涵盖所有组合。

String[] a = new String[] {"A", "B", "C"};
for (int mask = 0 ; mask != 1<<a.length ; mask++) {
    for (int i = 0 ; i != a.length ; i++) {
        if ((mask & 1<<i) != 0) {
            System.out.print("* ");
        } else {
            System.out.print(a[i]+" ");
        }
    }
    System.out.println();
}

Demo. 演示。

You can use a recursive function to get the current string and one index and one time change the character at that index to * and another time call the function without changing the character at that index. 您可以使用递归函数获取当前字符串和一个索引,然后一次将该索引处的字符更改为*而另一次调用该函数而无需更改该索引处的字符。 Print the result when index reaches end of the string: 当索引到达字符串的末尾时,输出结果:

public class Main{
    public static void main(String args[]){
        f(new StringBuilder("ABC"),0);
    }

    public static void f(StringBuilder str, int index){
        if (index == str.length()){
            System.out.println(str);
            return;
        }
        f(str, index+1);
        char c = str.charAt(index);
        str.setCharAt(index, '*');
        f(str, index+1);
        str.setCharAt(index, c);
    }
}

output 产量

ABC
AB*
A*C
A**
*BC
*B*
**C
***

My solution is a modification of @dasblinkenlight solution where I'm using recursive function and not mask bit. 我的解决方案是@dasblinkenlight解决方案的修改,其中我使用的是递归函数,而不是掩码位。 My solution is in javascript. 我的解决方案是在javascript中。

 var arr = ['A', 'B', 'C'], len = arr.length, pattern = function(startIndex, arr) { var newArr = [].concat(arr), i; newArr[startIndex] = '*'; console.log(newArr.toString()); for (i = startIndex + 1; i < len; i++) { pattern(i, newArr); } }; console.log(arr.toString()) for (i = 0; i < len; i++) { pattern(i, arr); } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM