这是数学中的组合问题吧。
AB,AC,AD,BC,BD,CD不是Cn2。可以用for(int i =0;i< length;i++){
  for(int j =i+1;i< length;i++){
    ..
  }
}完成,其他组合应该类似吧

解决方案 »

  1.   

    错了for(int i =0;i< length;i++){
      for(int j =i+1;j< length;j++){
        ..
      }
    }
      

  2.   


    谢谢你的回答,但是因为我这边是有很多大小不同的二维数组,这个基本的for loop我有想过的,但是因为每个二维数组的大小不一,这些组合有些是取到4,有些是取到6,或者取到其他别的数,单纯用for loop我觉得好像搞不定。
      

  3.   


    不好意思,我可能描述不太清楚,浪费你的时间了。
    其实是这样的,我现在想找寻一个方法可以遍历二维数组的所有组合,如我在一楼描述的那个例子一样,          *        A         B        C       D
              1       0.2      0.3     0.4    0.5
              2       0.3      0.4      0.2    0.5
              3       0.5      0.2      0.9     0.1
              ...       .....      .....        .....     .....(1).这是个二维数组,也可以说是个表,这个表的大小是不一的,也就是不是所有表的列(columns)都是只有ABCD,还有可能只有ABC,ABCDE,ABCDEF等等更多的其他可能
    (2).行(rows)的数目也是不确定的
    (3). 中间的数据,比如上面的例子,A-1 0.2说明A在完成1号题目的时候用了0.2秒,其他以此类推
    (4). 我的手头有个标准,比如标准是0.3,高于0.3就不合格,所有都低于0.3的时候就取最小的那个,我现在就需要遍历这个二维数组的所有组合,看哪个组合符合标准的最多(就是并集最大)。 比如AB在0.3的标准下,100题一共解了80题,AC在0.3的标准下,100题一共解了90题,ABC在0.3的标准下,100题一共解了96题,以此类推本人语言组织能力欠佳,造成的不便麻烦谅解一下,还有不清晰的我会继续补充的
      

  4.   


    不好意思,我可能描述不太清楚,浪费你的时间了。
    其实是这样的,我现在想找寻一个方法可以遍历二维数组的所有组合,如我在一楼描述的那个例子一样,          *        A         B        C       D
              1       0.2      0.3     0.4    0.5
              2       0.3      0.4      0.2    0.5
              3       0.5      0.2      0.9     0.1
              ...       .....      .....        .....     .....(1).这是个二维数组,也可以说是个表,这个表的大小是不一的,也就是不是所有表的列(columns)都是只有ABCD,还有可能只有ABC,ABCDE,ABCDEF等等更多的其他可能
    (2).行(rows)的数目也是不确定的
    (3). 中间的数据,比如上面的例子,A-1 0.2说明A在完成1号题目的时候用了0.2秒,其他以此类推
    (4). 我的手头有个标准,比如标准是0.3,高于0.3就不合格,所有都低于0.3的时候就取最小的那个,我现在就需要遍历这个二维数组的所有组合,看哪个组合符合标准的最多(就是并集最大)。 比如AB在0.3的标准下,100题一共解了80题,AC在0.3的标准下,100题一共解了90题,ABC在0.3的标准下,100题一共解了96题,以此类推本人语言组织能力欠佳,造成的不便麻烦谅解一下,还有不清晰的我会继续补充的
    “这个表的大小是不一的”,不懂?难道你在遍历它的时候,还不能确定吗?,你在遍历二维数组的时候,有多少行,每行有多少列,应该是确定了的吧
      

  5.   


    不好意思,我可能描述不太清楚,浪费你的时间了。
    其实是这样的,我现在想找寻一个方法可以遍历二维数组的所有组合,如我在一楼描述的那个例子一样,          *        A         B        C       D
              1       0.2      0.3     0.4    0.5
              2       0.3      0.4      0.2    0.5
              3       0.5      0.2      0.9     0.1
              ...       .....      .....        .....     .....(1).这是个二维数组,也可以说是个表,这个表的大小是不一的,也就是不是所有表的列(columns)都是只有ABCD,还有可能只有ABC,ABCDE,ABCDEF等等更多的其他可能
    (2).行(rows)的数目也是不确定的
    (3). 中间的数据,比如上面的例子,A-1 0.2说明A在完成1号题目的时候用了0.2秒,其他以此类推
    (4). 我的手头有个标准,比如标准是0.3,高于0.3就不合格,所有都低于0.3的时候就取最小的那个,我现在就需要遍历这个二维数组的所有组合,看哪个组合符合标准的最多(就是并集最大)。 比如AB在0.3的标准下,100题一共解了80题,AC在0.3的标准下,100题一共解了90题,ABC在0.3的标准下,100题一共解了96题,以此类推本人语言组织能力欠佳,造成的不便麻烦谅解一下,还有不清晰的我会继续补充的
    “这个表的大小是不一的”,不懂?难道你在遍历它的时候,还不能确定吗?,你在遍历二维数组的时候,有多少行,每行有多少列,应该是确定了的吧遍历某长表的时候大小和所有东西是能够确定的,但是好像上面的哥们回答的一样,如果要用for loop,那么这个for loop的数量是根据表的大小而改变的,比如两个为一组合的时候要用两个for loops,三个为一组合时候要用三个for loops。
               如: 
                      AB,AC,AD.... --->   for(.....)
                                                           for(....)
                      ABC,ABD.....---->   for(.....)
                                                           for(....)
                                                               for(....)
                 正如我上面讲得,表的大小是不一的,有些可能取AB,AC等两个的组合就ok了,有些可能要取ABCDEF等等等其他组合(根据表的长度来确定),我现在主要是想解决组合问题,不知道如何能够有序不重复的遍历所有组合。不知道描述清楚没,谢谢你的回复:)
                                                               
      

  6.   

    c/c++底下就会,java底下不太懂,而且表示没想通如何将动态申请内存应用到解决这个组合问题上,望大神赐教:)
      

  7.   

    c/c++底下就会,java底下不太懂,而且表示没想通如何将动态申请内存应用到解决这个组合问题上,望大神赐教:)byte size = 1;  
            long allocateMemory = UNSAFE.allocateMemory(size);  
            UNSAFE.putAddress(allocateMemory, value);  
            long readValue = UNSAFE.getAddress(allocateMemory); 
    我非大神,这是java的申请内存方式。百度 unsafe 
      

  8.   

    c/c++底下就会,java底下不太懂,而且表示没想通如何将动态申请内存应用到解决这个组合问题上,望大神赐教:)byte size = 1;  
            long allocateMemory = UNSAFE.allocateMemory(size);  
            UNSAFE.putAddress(allocateMemory, value);  
            long readValue = UNSAFE.getAddress(allocateMemory); 
    我非大神,这是java的申请内存方式。百度 unsafe 
    谢谢回复,能否告诉我一下如何将这个方法应用在我这个问题上呢?谢谢你帮我查资料,我主要是在思路上没能理顺,能否告知一下?谢谢:)
      

  9.   

    楼主对题目做了很多解释和补充,我也没看完,不好意思。不过我就楼主原来的题目给出自己答案。      AB,AC,AD,BC,BD,CD
          ABC,ABD,BCD
          ABCD
    这些应该针对的是一维数组的组合,如果在加上A,B,C,D,即数组{A,B,C,D}的所有组合。
    如果楼主这边仅是想要得到这些所有的组合形式(以String形式输出),而非以乘法的性质得出算数结果希望下面的代码对你有帮助,绝对是原创。
    我这边就假设这个一维数组的长度不清楚,并且得到所有的组合(去除A,B,C,D)以二维数组的性质保存组合,
    即,{{  AB,AC,AD,BC,BD,CD},{ ABC,ABD,BCD},{  ABCD}}此二维数组,本人论坛新人,请多帮助。
    今天时间不多了,还要休息,先把代码思路敲出来给楼主看一下。
    public class Combination {
    public static void main(String[] args){
    String[] arr={"A","B","C","D"};
    getTwoDimensionArray(arr);
    } public static String[][] getTwoDimensionArray(String[] arr) {


    }
    public static String[] getCombination(String[] arr, int n){
    /**从一个一维数组中取得n个元素所构成的组合*/
    //这里采取类似选择排序的for循环方式
    //这里还要采用递归的算法getCombination(n,arr)要利用getCombination(n-1,arr);n>=2;
    /*if(n>=2){
     * for(int j=0;j<getCombination(n,arr).length;j++){
    for(int i=0;i<getCombination(n-1,arr).length;i++){
    getCombination(n,arr)[j]=CurrentValue+getCombination(n-1,arr)[i];}
    }
    }
    }
    if(n=1){
    for(int i=0;i<arr.length;i++){
    getCombination(1,arr)[i]=arr[i];
    }}*/
    //其中arr要调用arr.substring(n-1,length);
    String CurrentValue;

    int CurrentIndex;




    //StringBuilder ss=new StringBuilder();

    }
    /*public static int getLength(String[] arr,int n){
    //计算从一个一维数组中取得n个元素所构成的组合的个数
     * 这个方法存在必要性未知
    }*/
    }
      

  10.   


    //代码重发一下
    public class Combination {
    public static void main(String[] args){
    String[] arr={"A","B","C","D"};
    getTwoDimensionArray(arr);
    } public static String[][] getTwoDimensionArray(String[] arr) {


    }
    public static String[] getCombination(String[] arr, int n){
    /**从一个一维数组中取得n个元素所构成的组合*/
    //这里采取类似选择排序的for循环方式
    //这里还要采用递归的算法getCombination(n,arr)要利用getCombination(n-1,arr);n>=2;
    /*if(n>=2){
     * for(int j=0;j<getCombination(n,arr).length;j++){
    for(int i=0;i<getCombination(n-1,arr).length;i++){
    getCombination(n,arr)[j]=CurrentValue+getCombination(n-1,arr)[i];}
    }
    }
    }
    if(n=1){
    for(int i=0;i<arr.length;i++){
    getCombination(1,arr)[i]=arr[i];
    }}*/
    //其中arr要调用arr.substring(n-1,length);
    String CurrentValue;

    int CurrentIndex;




    //StringBuilder ss=new StringBuilder();

    }
    /*public static int getLength(String[] arr,int n){
    //计算从一个一维数组中取得n个元素所构成的组合的个数
     * 这个方法存在必要性未知
    }*/
    }
      

  11.   

    public class Combination {
    //发帖还不熟悉,所以再重发一下。
    public static void main(String[] args){
    String[] arr={"A","B","C","D"};
    getTwoDimensionArray(arr);
    } public static String[][] getTwoDimensionArray(String[] arr) {


    }
    public static String[] getCombination(String[] arr, int n){
    /**从一个一维数组中取得n个元素所构成的组合*/
    //这里采取类似选择排序的for循环方式
    //这里还要采用递归的算法getCombination(n,arr)要利用getCombination(n-1,arr);n>=2;
    /*if(n>=2){
     * for(int j=0;j<getCombination(n,arr).length;j++){
    for(int i=0;i<getCombination(n-1,arr).length;i++){
    getCombination(n,arr)[j]=CurrentValue+getCombination(n-1,arr)[i];}
    }
    }
    }
    if(n=1){
    for(int i=0;i<arr.length;i++){
    getCombination(1,arr)[i]=arr[i];
    }}*/
    //其中arr要调用arr.substring(n-1,length);
    String CurrentValue;

    int CurrentIndex;




    //StringBuilder ss=new StringBuilder();

    }
    /*public static int getLength(String[] arr,int n){
    //计算从一个一维数组中取得n个元素所构成的组合的个数
     * 这个方法存在必要性未知
    }*/
    }
      

  12.   


    谢谢! 十分感谢你花时间思考我的问题和写代码给我。 我试了一下这个方法,好像跟我想要达成的目标不太吻合。 我本质上不是只是想要ABCD的组合排列,而是我要根据他们的排列,比如现在是AB,然后纵向比对AB这两列下面的数据,再比如现在是BCD,我就需要比对BCD这三列下面的数据。
      

  13.   


    谢谢! 十分感谢你花时间思考我的问题和写代码给我。 我试了一下这个方法,好像跟我想要达成的目标不太吻合。 我本质上不是只是想要ABCD的组合排列,而是我要根据他们的排列,比如现在是AB,然后纵向比对AB这两列下面的数据,再比如现在是BCD,我就需要比对BCD这三列下面的数据。看了一下你的需求,考虑十字链表实现
      

  14.   

    假设对于字段A, B, C, D, E,令E=2^0, D=2^1, C=2^2, B=2^3, A=2^4,则直接一个循环
    for (i=1; i<2^5; i++) {
        //求出i的二进制表示,若相应的位为1,则将相应列纳入集合,然后拼接
    }这样就可以了
      

  15.   


    public class Combination {
    public static void main(String[] args){
    String[] arr={"A","B","C","D","E"};
    String[][] arrTD=getTwoDimensionArray(arr);
    /*for(int i=0;i<getCombination(arr,3).length;i++)
    System.out.print(" "+getCombination(arr,3)[i]);
    */
    for(int i=0;i<arrTD.length;i++){
    for(int j=0;j<arrTD[i].length;j++){
    System.out.print(" "+arrTD[i][j]);
    }
    System.out.println();
    }
    } public static String[][] getTwoDimensionArray(String[] arr) {
    /**将getCombination所有一维数组赋值给新数组*/
    String[][] newarr=new String[arr.length][];
    for(int n=1;n<=arr.length;n++){
    newarr[n-1]=getCombination(arr,n);
    }
    return newarr;

    }

    public static String[] getCombination(String[] arr, int n){
    //这里还要检测n必须不超过arr.length,这里就省略了
    /**从一个一维数组中取得n个元素所构成的组合,并视AB BA为相同组合*/
    //这里采取类似选择排序的for循环方式
    //这里还要采用递归的算法getCombination(n,arr)要利用getCombination(n-1,arr);n>=2;
    String[] newarr=new String[getLength(arr,n)];
    //System.out.println(n+" n "+newarr.length);

    //System.out.println((n-1)+" n-1 "+newarrminus1.length);

    //int currentIndex=0;


    int count=0;
    if(n==1){
    for(int i=0;i<arr.length;i++){
    newarr[i]=arr[i];
    }

    }
    if(n>=2){

    for(int j=0;j<arr.length-1;j++){

    String currentValue=arr[j];
    int len=newarr.length;
    int lensub=subArray(arr,j+1).length;
    int lengetCombinationsub=getCombination(subArray(arr,j+1),n-1).length;
    /**for(int i=0;i<len;i++){*/
    for(int k=0;k<lengetCombinationsub;k++){
    //System.out.println(n+" +"+count);
    //System.out.print(j+" "+getCombination(subArray(arr,j+1),n-1)[k]+"  ");
    //这里出现容易一个错误,getCombination(subArray(arr,j+1),n-1)的长度问题

    if(lensub>=n-1){
    newarr[count]=currentValue+
    getCombination(subArray(arr,j+1),n-1)[k];
    }


    count++;
    }


    }//for 1

    }



    return newarr;
    //StringBuilder ss=new StringBuilder();

    }
    public static int getLength(String[] arr,int n){

    //计算从一个一维数组中取得n个元素所构成的组合的个数
    int len =arr.length;
    /*if(n==2)
    System.out.println(n+"  arr.len  "+len);*/
    int getlen =0;
    int fenzi =len;
    int fenmu =1;
    for(int i=1;i<n;i++){
    int temp =len;
    fenzi=fenzi*(temp-i);

    /*if(n==2)
    System.out.println(n+" fenzi "+fenzi+" "+len);*/
    int demp=1;
    fenmu=fenmu*(demp+i);

    }
    getlen=fenzi/fenmu;
    //System.out.println(getlen);
    return getlen;
    }
    public static String[] subArray(String[] arr ,int n){
    /**分割一个字符串数组,获得一个新的字符串数组从n位到len-1位*/
    int len=arr.length;
    String[] newarr=new String[len-n];
    System.arraycopy(arr, n, newarr, 0, len-n);
    //System.out.println(newarr[0]+" "+newarr[len-n-1]+" "+(len-n));
    return newarr;

    }
    }
    不管怎样代码我还是敲出来了,对于你说的条件,我会重新再遍
    因为涉及了递归方法,debug了好久,才把程序给敲出来。
      

  16.   

    我本质上不是只是想要ABCD的组合排列,而是我要根据他们的排列,比如现在是AB,然后纵向对比AB这两列下面的数据,再比如现在是BCD,我就需要对比BCD这三列下面的数据。
               *        A         B        C       D
              1       0.2      0.3     0.4    0.5
              2       0.3      0.4      0.2    0.5
              3       0.5      0.2      0.9     0.1请说出具体比较方式,BCD三列下的数据如何比较,比较均值最大值还是比较平方和最小值还是比较B1、C2、D3还是其他类型的数学比较方式,这些比较方式所要用到class不一样,敲程序代码思路也不一样。
    但是只要排列已经全部求出,根据求出排列的长度,每个下标的字符,这些问题都是可解决的,就是再读入这些数据时,需要费些功夫。
    还有本人初学java,太高深的知识点还不知道,不过对javaSE上大部分内容还是很熟的。
      

  17.   

    个人见解,楼主你所说不能用for循环遍历,那是因为排列的可能性太多,必须这些可能性组成相对应的数组,然后再统一遍历。
       先算ABCDE等列出所有可能排列的可能,将这些可能组成一个个二维数组,将这些二维数组放到一个数组中,然后将可能全部遍历出来,再用你的条件挑出你想要的数据。
      

  18.   

    下面是怎么把可能性装到代码,剩下的你自己搞定吧
    public class test{
    static double [] a={0.1,0.4,0.5};
    static double [] b={0.3,0.2,0.6};
    static double [] c={0.4,0.1,0.4};
    static double [] d={0.7,0.6,0.2};
    static double [] f={0.3,0.5,0.2};
    static double [][] arry={a,b,c,d,f};

    public static void main(String[] args) {
    method(arry);

    }
    public static void method(double [][]arr){
    //装可能行排列方式
    List<double[][]> ar=new ArrayList<double[][]>();

    for (int i = 0; i < arr.length; i++) {
    for (int j =i+1; j < arr.length; j++) {
    double [][] newarr=new double[2][];
    newarr[0]=arr[i];
    newarr[1]=arr[j];
    ar.add(newarr);
    for (int k = j+1; k < arr.length; k++) {
    double [][] newarr1=new double[3][];
    newarr1[0]=arr[i];
    newarr1[1]=arr[j];
    newarr1[2]=arr[k];
    ar.add(newarr1);
    for (int x = k+1; x < arr.length; x++) {
    double [][] newarr2=new double[4][];
    newarr2[0]=arr[i];
    newarr2[1]=arr[j];
    newarr2[2]=arr[k];
    newarr2[3]=arr[x];
    ar.add(newarr2);

    for (int l = x+1; l < arr.length; l++) {
    double [][] newarr3=new double[5][];
    newarr3[0]=arr[i];
    newarr3[1]=arr[j];
    newarr3[2]=arr[k];
    newarr3[3]=arr[x];
    newarr3[4]=arr[l];
    System.out.println(Arrays.toString(arr[l]));
    ar.add(newarr3);
    }
    }


    }


    }
    }

    for (int i = 0; i < ar.size(); i++) {
    double [][] temp=ar.get(i);
    for (int j = 0; j < temp.length; j++) {
    for (int k = 0; k < temp[j].length; k++) {

    System.out.print(Arrays.toString(temp[j])+" ");
    }
    }

    System.out.println();

    }

    }
    }
      

  19.   


    谢谢! 十分感谢你花时间思考我的问题和写代码给我。 我试了一下这个方法,好像跟我想要达成的目标不太吻合。 我本质上不是只是想要ABCD的组合排列,而是我要根据他们的排列,比如现在是AB,然后纵向比对AB这两列下面的数据,再比如现在是BCD,我就需要比对BCD这三列下面的数据。看了一下你的需求,考虑十字链表实现
    好的,我去学习一下相关资料,谢谢
      

  20.   


    十分感谢!太辛苦你了!你说得对,我没描述好,我的想法是:
                   我手头上有个标准,比如对应上面这个表,我有一个标准0.4,对于BCD这三列下的数据,是B1,C1,D1这样一行里的数据跟标准(这个例子里:0.4)比较,然后如果三个都超过0.4,则不做任何事情,如果只有一个低于0.4,那么这题算是那个选手赢了,如果都低于0.4,就分数最低(其实这里的分数是时间,所以是最快的人赢),最后是要计算一共搞定了多少题
                   从另一种角度来说:
                     如果把每个列都算是一个集合,我的目标就是计算不同集合的并集。
      

  21.   

    那LZ的意思是想找出所有被1个或者几个选手搞定的题目,并列出那些题目的优胜者?
    如果是这样的话,直接一个2重循环就可以搞定了,根本不用求全部的并集,这可是n*n和2^n之间的时间差别啊
      

  22.   

    昨天太累了,看到楼主回帖也很晚了,所以没回帖。根据楼主所说我可以重新再试试,不过有朋友说用二进制替换会简单
    假设对于字段A, B, C, D, E,令E=2^0, D=2^1, C=2^2, B=2^3, A=2^4,则直接一个循环
    for (i=1; i<2^5; i++) {
        //求出i的二进制表示,若相应的位为1,则将相应列纳入集合,然后拼接
    }我晚上仔细想了想,这个思路的弊端在下:
    问题1."E"=2^0,这个过程中,既要保留2^0,又需要保留“E”,也就是需要重新申请变量,并且添加一个方法,如下:
    String E="E";
    int e=2^0;
    int method(String E){
    if(E.equals("E))}return 2^0;当然实际再去写这个程序时,还要做很多for loop,大家也能很容易知道,就不写完整了。
    问题2. //求出i的二进制表示,若相应的位为1,则将相应列纳入集合,然后拼接,确实很漂亮的想法,我也不得承认这是个快速得到所有排序的方法。只需要两个方法:1.把十进制数转换为2进制的方法(java里提供了);2.根据二进制得到对应字符串。
    但是这个方法缺陷就是无法给出
    AB,AC,AD,BC,BD,CD
          ABC,ABD,BCD
          ABCD               像这样有规律的排序,要实现这个有规律的排序用二进制的方法就是累赘了。
    个我见解而已,只是把我自己的理解说出来。
      

  23.   


    //不规则数组
    int [][] arr;
    for(int i = 0 ; i < arr.length ; i++){
         for(int j = 0; j<arr[i].length; j++){
         
         }
    }你要的是不是这种形式?
      

  24.   

    但是我的标准是根据组合变得,是计算出来的,并不是一直不变的
    请问这个标准生成的规则是什么?总觉得全遍历是一个很耗时间的操作有几种情况,对了,总时间(即总标准)是固定的,比如我取2.4(这2.4是固定的)
    首先是时间均分,两个为一组合的时候就是2.4/2=1.2,即AB下的数据跟1.2比;三个为一组合的时候就是2.4/3=0.8,即ABC下地数据跟0.8比;以此类推
    然后是时间不均分,则根据选手的解题能力来计算其百分比,比如A+B+C一共解决了200题,然后A解决了100题,B解决了60题,C解决了40题,然后给A的标准是(100/200)*2.4,B的标准是(60/200)*2.4,C的标准是(40/200)*2.4.本质上这个系列问题就是最优化问题,不过我这个是最简单最不准确地最优化=。=
    不知道讲清楚木有。。
      

  25.   

    楼主你的意思是不是行代表方法,列代表用时,在一个限定的总时间控制下找到解决问题做多的一个方法集(例如ab)。举个例子:假如我最后选择了AB,时间要求0.3s,第i题A,B之中任意一个方法时间不多于0.3s,这道题就算被解决?
      

  26.   

    java严格意义上来说是没有二位数组的 只是一维数组的元素是一维数组而已
    你可以这样      String[][] ss = new String[5][];//这个定义的时候第一个参数是必须的吧 就算不是new的 其他获得的长度一定有的
    for (int i = 0; i < ss.length; i++) {
    for (int j = 0; j < ss[i].length; j++) {
    System.out.println(ss[i][j]);//这个元素绝对有 不会下标越界
    }
    }
      

  27.   

    兄台你对我帮助超大的,十分感谢你! 一起努力一起探索吧:)
    嗯,我现在也在努力学习java,打牢基础,互相帮助吧,我已经关注你了,有新问题时互相帮助呗。