生成"选择"的组合操作

时间:2016-09-08 20:56:55

标签: java combinatorics

我想执行一个变体" 6选择2"操作。我写了以下代码。

public void choosePatterns(){
    String[] data = {"1", "2", "3", "4", "5", "6"};
    String[] originalPattern = new String[15];
    int index = 0;
    for(int i = 0; i < (6-1); i++)
    {
        for(int j = i+1; j < 6; j++)
        {
            System.out.println(i + "," +j);
        }
    }
}

我的代码到目前为止生成所有可能的组合&#34; 6选择2。&#34;但是,我想改变这一点并打印所有剩余的数字。到目前为止,如果&#34; 6的一个组合选择2&#34;是&#34; 3&#34;和&#34; 4,&#34;然后我想打印&#34; 1,&#34; &#34; 2,&#34; &#34; 5,&#34; &#34; 6&#34。

我不确定如何最有效地做到这一点。啰嗦的方式是删除&#34;数据&#34;中的那些指数。数组,移位数据,以便没有间隙,然后打印数组。但有更快,更有效的方法吗?

3 个答案:

答案 0 :(得分:0)

好吧,既然你想要[6选择X]变得动态(X = 2,3,4,...)并且不想为每个案例添加特定数量的for循环,我想递归应该可以解决问题。

让我们看一下示例代码:

public void choosePatterns(){
    String[] data = {"1", "2", "3", "4", "5", "6"};
    int deep = 3; // << This value is the X above
    deep = deep > data.length ? data.length : deep; // << prevent X over data length
    printCombine(data, new ArrayList<Integer>(), deep); // Main business here
}

printCombine方法内容:

private void printCombine(final String[] data, final List<Integer> selectedIdxs, final int deep) {
    if(deep == 1) {  // When come to the last combine number, print out
        StringBuilder sb = new StringBuilder();
        for(int i : selectedIdxs) {
            sb.append(data[i]);
            sb.append(", ");
        }
        String prefixCombine = sb.toString();

        for(int i = 0; i < data.length; i++) {
            if(!selectedIdxs.contains(i)) {
                System.out.println(new StringBuilder(prefixCombine).append(data[i]).toString());
            }
        }
    } else {
        for(int i = 0; i < data.length; i++) {
            if(!selectedIdxs.contains(i)) {
                // Mark the selected indices of the combination
                List<Integer> curSelectedIdx = new ArrayList<Integer>();
                curSelectedIdx.addAll(selectedIdxs);
                curSelectedIdx.add(i);
                printCombine(data, curSelectedIdx, deep - 1);
            }
        }
    }
}

答案 1 :(得分:0)

我改为使用一组int,只是为了显示目的而将值加1:

public static void choosePatterns(){
    int[] display = new int[6];
    for(int i = 0; i < (6-1); i++)
    {
        for(int j = i+1; j < 6; j++)
        {
            display[0] = i+1;
            display[1] = j+1;
            int x = 2;
            for(int k = 0; k < 6; k++)
            {
                if((k != i) && (k != j))
                    display[x++] = k+1;
            }
            System.out.println(Arrays.toString(display));
        }
    }
}

答案 2 :(得分:0)

这是一种方法。

public static void choosePatterns(int total, int toChoose) {
  List<Integer> indices = IntStream.range(1, toChoose + 1).mapToObj(i -> Integer.valueOf(0)).collect(Collectors.toList());
  resetIndex(indices, 0, 1, total);
  while (true) {
    System.out.println("chosen: " + indices);
    System.out.print("not chosen: ");
    for (int i = 1; i <= total; i++) {
      if (! indices.contains(Integer.valueOf(i))) {
        System.out.print(i + " ");
      }
    }
    System.out.println("\n");

    if (! incrementIndices(indices, indices.size() - 1, total)) {
      break;
    }
  }
}

public static boolean resetIndex(List<Integer> indices, int posn, int value, int total) {
  if (value <= total) {
    indices.set(posn, value);
    return posn == indices.size() - 1 ? true : resetIndex(indices, posn + 1, value + 1, total);
  } else {
    return false;
  }
}

public static boolean incrementIndices(List<Integer> indices, int posn, int total) {
  if (indices.get(posn) < total) {
    indices.set(posn, indices.get(posn) + 1);
  } else {
    int resetPosn = posn;
    do {
      if (resetPosn-- == 0) return false;
    } while (! resetIndex(indices, resetPosn, indices.get(resetPosn) + 1, total));
  }
  return true;
}

public static void main(String[] args) throws IOException {
  choosePatterns(6, 2);
}

打印出来:

chosen: [1, 2]
not chosen: 3 4 5 6 

chosen: [1, 3]
not chosen: 2 4 5 6 

chosen: [1, 4]
not chosen: 2 3 5 6 

chosen: [1, 5]
not chosen: 2 3 4 6 

chosen: [1, 6]
not chosen: 2 3 4 5 

chosen: [2, 3]
not chosen: 1 4 5 6 

chosen: [2, 4]
not chosen: 1 3 5 6 

chosen: [2, 5]
not chosen: 1 3 4 6 

chosen: [2, 6]
not chosen: 1 3 4 5 

chosen: [3, 4]
not chosen: 1 2 5 6 

chosen: [3, 5]
not chosen: 1 2 4 6 

chosen: [3, 6]
not chosen: 1 2 4 5 

chosen: [4, 5]
not chosen: 1 2 3 6 

chosen: [4, 6]
not chosen: 1 2 3 5 

chosen: [5, 6]
not chosen: 1 2 3 4