用于在Java中查找集合的组合的递归算法

时间:2011-08-06 10:18:08

标签: java recursion combinations

我试图找到一些关于如何在Java中找到给定集合(可能是字符串或整数数组)的所有组合的示例。我发现了这段代码(在http://introcs.cs.princeton.edu/java/23recursion/Combinations.java.html中找到。我在这里只复制了相关部分。):

// print all subsets of the characters in s
public static void comb1(String s) { comb1("", s); }

// print all subsets of the remaining elements, with given prefix 
private static void comb1(String prefix, String s) {
    if (s.length() > 0) {
        System.out.println(prefix + s.charAt(0));
        comb1(prefix + s.charAt(0), s.substring(1));
        comb1(prefix,               s.substring(1));
    }
}  

// read in N from command line, and print all subsets among N elements
public static void main(String[] args) {
   int N = Integer.parseInt(args[0]);
   String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   String elements = alphabet.substring(0, N);

   // using first implementation
   comb1(elements);
   System.out.println();
}

但是,我真的不明白它是如何运作的。有人关心解释吗?

2 个答案:

答案 0 :(得分:3)

创建给定集合的所有组合非常简单。你有N个元素,在每个组合中元素是否存在,所以你有2 ^ N个组合。那个递归函数正是如此。它从该列表中选取每个元素并创建包含它的组合并创建不包含它的组合。注意:它不会打印出空组合。

如果仍然不清楚,请创建一个简短的测试字符串(例如:3个字符),启动调试器并查看其工作原理。

答案 1 :(得分:0)

Java程序从main开始。这个参数应该是一个整数。它将整数存储在N中。如果用户输入java并且程序名称带有3,那么N将被设置为3.这用于剥离字母表的前N个字母并将它们放在元素中。 (在我们的示例中,abc)。然后它调用comb1(abc),即首先列出的公共comb1。

接下来,comb1使用两个参数调用私有comb1,一个空字符串和abc

现在递归开始了。私有comb1采用前缀和字符串(在第一种情况下为空字符串和abc)。如果字符串不为空,则为:

  1. 打印第一个字符
  2. 以递归方式调用自身,前缀为+第一个字符作为新前缀,余数为新字符串,
  3. 使用与新前缀相同的前缀以及除第一个字符之外的所有字符作为新字符串递归调用自身。
  4. (这里有很多人会轻微颤抖......盯着它,坚持下去,成为电脑,意思就会到来。)

    (Top level)
    comb1("", "abc") -> *1* a   *2* comb1("a", "bc") *3* comb1("", "bc")
    
    (Second level)
    comb1("a", "bc") -> *1* ab  *2* comb1("ab", "c") *3* comb1("a", "c")
    comb1("", "bc")  -> *1* b   *2* comb1("b", "c")  *3* comb1("", "c")
    
    (Third level)
    comb1("ab", "c") -> *1* abc *2* comb1("abc", "") *3* comb1("ab", "")
    comb1("a", "c")  -> *1* ac  *2* comb1("a", "")   *3* comb1("a", "")
    
    comb1("b", "c")  -> *1* bc  *2* comb1("bc", "")  *3* comb1("b", "")
    comb1("", "c")   -> *1* c   *2* comb1("c", "")   *3* comb1("", "")
    
    (Fourth level)
    comb1("ab", "") -> (immediate return, ending recursion) 
    comb1("a", "") -> (immediate return, ending recursion)
    comb1("b", "") -> (immediate return, ending recursion)
    comb1("", "") -> (immediate return, ending recursion)