【问题标题】:Java - Listing combinationsJava - 列表组合
【发布时间】:2012-02-12 14:35:19
【问题描述】:

我正在编写一个程序来列出字母 A、B、C 和 D 的所有可能组合。我已经成功编写了一个程序来列出所有可能的排列。

但是,我将如何重写程序以工作并产生所有组合(即:ABCD = DCBA 和 AB = BA,所以只要有一个,就不需要列出另一个)。

到目前为止,我当前程序的代码是:

import java.util.ArrayList;

public class Perms {

    public static void main(String[] args) {

        ArrayList<Character> characters = new ArrayList<Character>();

        characters.add('A');
        characters.add('B');
        characters.add('C');
        characters.add('D');

        int count = 0;

        for (int i = 0; i < characters.size(); i++) {
            for (int j = 0; j < characters.size(); j++) {
                for (int k = 0; k < characters.size(); k++) {
                    for (int d = 0; d < characters.size(); d++) {
                        count++;
                        System.out.println(count + ": " + characters.get(i) + characters.get(j) + characters.get(k) + characters.get(d));
                    }
                }
            }
        }

    }
}

【问题讨论】:

  • 对不起,您能否更清楚地说明您的问题。因为,在集合 {A,B,C,D} 中只有一个包含四个元素的字符串,顺序无关紧要:是 ABCD 还是 BCDA 还是 CDAB.... 所以,只有一个字符串,您可以从中选择一个.我认为您的问题是:列出所有集合都是由 {A,B,C,D} 制成的。如果这是真的,那么一些答案是:{a} {B} {C} {D} {AB} {AC}......对吗?
  • 对不起;我的意思是打印 ABCD、ABC、AB 等。只是每组独特的字母。
  • 给定的代码不会生成所有可能的 ABCD 排列,而是生成所有长度为 4 的字母 ABCD 字符串。 AAAA,您的程序将打印的第一行,不是 ABCD 的排列。
  • m92,通过排列,顺序很重要。它位于the definition of a permutation。您正在寻找一个组合。

标签: java for-loop arraylist combinations


【解决方案1】:

您的第二种情况相当于 4 位二进制值的列表。假设 A 是最右边的数字,D 是最左边的数字。那么一共有16种组合:

DCBA
0000
0001
0010
0011
0100
...
1110
1111

每个组合解码如下:

DCBA
1010 = DB

因为B和D位置都有。

您有多种方法可以在 Java 中生成和/或解码二进制数。

例如,按位运算:

public static void main(String[] args) {

    // starting from 1 since 0000 is not needed
    for(int i=1; i<16; ++i) {

        // bitwise operation & detects 1 in given position,
        // positions are determined by sa called "masks" 
        // mask has 1 in position you wish to extract
        // masks are 0001=1, 0010=2, 0100=4 and 1000=8
        if( (i & 1) > 0 ) System.out.print("A");
        if( (i & 2) > 0 ) System.out.print("B");
        if( (i & 4) > 0 ) System.out.print("C");
        if( (i & 8) > 0 ) System.out.print("D");

        System.out.println("");

    }
}

【讨论】:

    【解决方案2】:

    这是我解决您问题的代码 :)

    很抱歉,我的答案看起来很丑,因为我只是 Java 的新手。

    import java.util.Vector;
    
    public class StackOverFlow {
    
        static int n ;
        static Vector<String> set;
        static int[] d ;
        public static void recursion(int t){
            if(t==n){
                PRINT();
                return;
            }
            d[t]=1;
            recursion(t+1);
            d[t]=0;
            recursion(t+1);
        }
    
        public static void PRINT(){
            System.out.println("ANSWER");
            for(int i=0;i<n;i++)
                if(d[i]==1) System.out.println(set.elementAt(i));
        }
    
    
        public static void main(String[] args) {                   
            n = 4;
            set = new Vector<String>(4);
            d = new int[6];
            set.add("a");
            set.add("b");
            set.add("c");
            set.add("d");
            recursion(0);
        }
    }
    

    【讨论】:

      【解决方案3】:
      // Returns all combinations of a List of Characters (as Strings)
      // THIS METHOD MODIFIES ITS ARGUMENT! Make sure to copy defensively if necessary
      List<String> charCombinations(List<Character> chars)
      {
        if(chars.isEmpty())
        {
          List<String> result = new ArrayList<String>();
          result.add("");
          return result;
        }
        else
        {
           Character    c      = chars.remove(0);
           List<String> result = charCombinations(chars);
           int          size   = result.size();
           for(int i = 0; i < size; i++)
             result.add(c + result.get(i));
           return result;
        }
      }
      

      我使用List 作为参数,因为Set 没有从集合中弹出单个项目的方法。

      【讨论】:

        【解决方案4】:

        看看Peter Lawrey's recursive solution,它处理包含重复值的列表的组合。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-07
          • 1970-01-01
          • 2010-10-12
          相关资源
          最近更新 更多