给出一串数字,算出所有组合值


public class AllOrderWithinNumbers {

public static void main(String...args){
int[] i = new int[]{1,2,4,5};
AllOrderWithinNumbers t = new AllOrderWithinNumbers();
ArrayList al = t.getOrders(i);
System.out.println(al.size());
System.out.println(al);
}

private ArrayList getOrders(int[] others){
ArrayList al = new ArrayList();
//如果只有一个数,则返回自身
if(others.length==1){
al.add(others[0]);
}else{
for(int i=0;i<others.length;i++){
int[] t = this.getLeftNumber(others,i);
ArrayList tmp = this.getOrders(t);
//tmp.add(0,others[i]); //uncomment this line and comment the blow line, to see what the result is
this.linkSubOrders(others[i],tmp);
//这里要进行判断,如果tmp中包含ArrayList,那么直接addAll,把每一个ArrayList作为子元件插入到al中,如果tmp不包含ArrayList,那么要把tmp作为一个整体插入
// al.add(tmp);// this line and the next 4 lines, you can compare the differences
if(tmp.get(0) instanceof ArrayList){
al.addAll(tmp);
}else{
al.add(tmp);
}
}
}
return al;
}

/**
*
* @param i 开头数
* @param tmp 除了开头数之外其它数字组成的排序,由于在多个ArrayList中,因此要把开头数插入到每个ArrayList开头
* 注意:由于tmp中会存在嵌套的ArrayList,因此这里要进行嵌套ArrayList递归,如[1,[2,[3,4][4,3]],[3,[2,4][4,2]]...]要转换成[1,2,3,4],[1,2,4,3],[1,3,2,4]...这样的形式
*/
private void linkSubOrders(int i, ArrayList tmp) {
if(tmp.get(0) instanceof ArrayList){
for(int j=0;j<tmp.size();j++){
ArrayList al = (ArrayList) tmp.get(j);
this.linkSubOrders(i, al);
}
}else{
tmp.add(0,i);
}
}

/**
* copy others to a new array, not including the i-th number
* @param others
* @param i
* @return
*/
private int[] getLeftNumber(int[] others, int i) {
int[] t = new int[others.length-1];
for(int j=0;j<others.length;j++){
if(j<i){
t[j] = others[j];
}
if(j==i){

}
if(j>i){
t[j-1] = others[j];
}
}
return t;
}
}


补:群里坦克大牛的一种写法,非常简洁:
[code]
private void test(){
char[] dictionaries = "ABC".toCharArray();
int limit = 1 << dictionaries.length;
for (int mask = 1; mask < limit; mask++) {
for (int submask = 1, i = 0; i < dictionaries.length; submask <<= 1, i++) {
if ((mask & submask) != 0) {
System.out.print(dictionaries[i]);
}
}
System.out.println();
}
}
[/code]
思路:首先知道所有组合数是2^n-1,也就是limit的大小, 对limit进行循环,这样就可以取出所有的组合了,注意submask,它是每循环一次左移一位,然后和mask进行&
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值