java列出所有组合_递归控制-列出所有组合

0.目录

1.递归思路

列出所有组合,例如从1,2,3,4中任取2个元素,求出所有的组合。

面对combinations([1,2,3,4], 2):

递归思路为:

选1 → combinations([2,3,4], 1)

不选1 → combinations([2,3,4], 2)

2.Java代码实现

2.1 分开考虑初始值

先分开考虑传入参数的初始值

/**

* Generates all combinations and output them,

* selecting n elements from data

*/

public void combinations(List data, int n) {

// initial value for recursion

if (data.isEmpty()) {

if (n == 0) {

// output empty list

}

return;

}

if (n < 0) {

return;

}

if (n == 0) {

// output empty list

return;

}

// select element 0

combinations(data.subList(1, data.size()), n - 1);

// un-select element 0

combinations(data.subList(1, data.size()), n);

}

2.2 合并各自初始条件

合并初始值条件后,考虑两个问题:

如何选择元素?如何输出?

/**

* Generates all combinations and output them,

* selecting n elements from data

*/

public void combinations(List data, int n) {

// how to select elements

// how to output

if (n == 0) {

// output all selected elements

return;

}

if (data.isEmpty()) {

// output empty list

return;

}

// select element 0

combinations(data.subList(1, data.size()), n - 1);

// un-select element 0

combinations(data.subList(1, data.size()), n);

}

2.3 维护side-effect

维护一个selected,也就是之前所选择的的所有元素。

/**

* Generates all combinations and output them,

* selecting n elements from data

*/

public void combinations(

List selected, List data, int n) {

if (n == 0) {

// output all selected elements

for (Integer i : selected) {

System.out.print(i);

System.out.print(" ");

}

System.out.println();

return;

}

if (data.isEmpty()) {

// output empty list

return;

}

// select element 0

selected.add(data.get(0));

combinations(selected, data.subList(1, data.size()), n - 1);

// un-select element 0

selected.remove(selected.size() - 1);

combinations(selected, data.subList(1, data.size()), n);

}

2.4 测试用例

测试程序是否正确运行:

public static void main(String[] args) {

Combinations comb = new Combinations();

comb.combinations(

new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 2);

}

运行结果为

6ed4a2374543cfa9306197b4b60a1e1a.png

多测几个极端用例

public static void main(String[] args) {

Combinations comb = new Combinations();

comb.combinations(

new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 2);

System.out.println("=================");

comb.combinations(

new ArrayList<>(), Arrays.asList(), 2);

System.out.println("=================");

comb.combinations(

new ArrayList<>(), Arrays.asList(), 0);

System.out.println("=================");

comb.combinations(

new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 1);

System.out.println("=================");

comb.combinations(

new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 0);

System.out.println("=================");

}

运行结果为

d3a8352fd722f8b4c1b341ef6a66f577.png

全部代码:

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

public class Combinations {

/**

* Generates all combinations and output them,

* selecting n elements from data

*/

public void combinations(

List selected, List data, int n) {

if (n == 0) {

// output all selected elements

for (Integer i : selected) {

System.out.print(i);

System.out.print(" ");

}

System.out.println();

return;

}

if (data.isEmpty()) {

// output empty list

return;

}

// select element 0

selected.add(data.get(0));

combinations(selected, data.subList(1, data.size()), n - 1);

// un-select element 0

selected.remove(selected.size() - 1);

combinations(selected, data.subList(1, data.size()), n);

}

public static void main(String[] args) {

Combinations comb = new Combinations();

comb.combinations(

new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 2);

System.out.println("=================");

comb.combinations(

new ArrayList<>(), Arrays.asList(), 2);

System.out.println("=================");

comb.combinations(

new ArrayList<>(), Arrays.asList(), 0);

System.out.println("=================");

comb.combinations(

new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 1);

System.out.println("=================");

comb.combinations(

new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 0);

System.out.println("=================");

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值