查找一组给定数字的给定数字的排列

时间:2014-07-03 21:44:36

标签: java set permutation dynamic-programming

假设给定的集合s = {2,3,4}和目标sum = 8 我想找到所有可能的排列,其总和接近目标。我的意思是总和介于: 目标减去集合中的最小数字(8-2)和目标加上集合中的最大数字(8 + 4),即:(sum> = 6)和(sum <= 8)。结果应如下:

2   2   2   2
2   2   3   
2   2   4   
2   3   2   
2   3   3   
2   4   2   
3   2   2   
3   2   3   
3   3   2   
3   4   2   
4   2       
4   3       
4   4

我必须用Java编写代码。我认为可以通过递归来完成。我已经看到了一些例子,比如找一个集合中的一个子集,其总和等于一个目标,但我的问题与此不同。 经过多次尝试后,我无法构建逻辑。

现在我正在使用以下代码以非常幼稚的方式进行此操作。但是,我想改进它。

package com.main;

public class MainClass {

static int sum =0;

static void setSum(){
    sum=0;
}

public static void perm2(int[] set, int target)
{
    int min=set[0];
    int max=set[0];

    for(int jj=0; jj<set.length; jj++){
        if(min>set[jj])
            min=set[jj];
        if(max<set[jj])
            max=set[jj];
    }

    int i=0;    
    do{ 
        if(sum<target){
            sum +=set[i];

            int j=0;
            do{
                sum =set[i]+set[j];

                if(sum>min+max)
                    if(sum<=target){
                        System.out.println(set[i]+","+set[j]);  

                    }else
                    {setSum();j=set.length;}

                j++;    
            }while(j<set.length);

        }else
        {setSum(); i=set.length;}

        i++;
    }while(i<set.length);
}

public static void perm3(int[] set, int target){

    int i=0;    
    do{         
        if(sum<target){
            sum +=set[i];                   
            int j=0;
            do{
                sum =set[i]+set[j];
                if(sum<target){

                    int k=0;
                    do{

                        sum =set[i]+set[j]+set[k];
                        if(sum<=target)                                 
                            System.out.println(set[i]+","+set[j]+","+set[k]);   
                        else
                        {setSum();k=set.length;}

                        k++;    
                    }while(k<set.length);

                }else
                {setSum();j=set.length;}

                j++;    
            }while(j<set.length);

        }else
        {setSum(); i=set.length;}

        i++;
    }while(i<set.length);

    perm2(set,target);
}

public static void perm4(int[] set, int target){    
    int i=0;    
    do{

        if(sum<target){
            sum +=set[i];                   
            int j=0;
            do{

                if(sum<target){
                    sum =set[i]+set[j];                         
                    int k=0;
                    do{
                        if(sum<target){
                            sum =set[i]+set[j]+set[k];  
                            int l=0;
                            do{
                                sum =set[i]+set[j]+set[k]+set[l];
                                if(sum<=target){

                                    System.out.println(set[i]+","+set[j]+","+set[k]+","+set[l]);

                                }else
                                {setSum();l=set.length;}


                                l++;    
                            }while(l<set.length);


                        }else
                        {setSum();k=set.length;}

                        k++;    
                    }while(k<set.length);


                }else
                {setSum();j=set.length;}

                j++;    
            }while(j<set.length);

        }else
        {setSum(); i=set.length;}

        i++;
    }while(i<set.length);

    perm3(set, target);
}

public static void main(String[] args) {

    int[] set = new int[]{2,3,4};
    int target = 8;

    perm4(set, target);

}

}

1 个答案:

答案 0 :(得分:0)

CombinatoricsLib 2.1是一个用于生成组合对象的java库。它基于java泛型,不依赖于其他库。您应该只将此库包含在项目中,并设置排列或组合的特定元素类型。

https://code.google.com/p/combinatoricslib/