【问题标题】:List all permutations & combinations in Integer Arraylist recursively递归地列出 Integer Arraylist 中的所有排列和组合
【发布时间】:2014-01-11 04:05:24
【问题描述】:

我有一个方法 perm1 可以打印字符串中所有字符的排列/组合

// print permutation / combination of the characters of the string s (in order)
public  static void perm1(String s) { perm1("", s); }
private static void perm1(String prefix, String s) {
    int N = s.length();
    if (N == 0) System.out.println(prefix); 
    else {
        System.out.println(prefix);
        for (int i = 0; i < N; i++)
           perm1(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, N));
    }
}

perm1 工作正常并产生所需的输出。

我正在尝试创建一个类似的方法perm2,它适用于整数数组列表

public static void perm2(ArrayList<Integer> a) {
    ArrayList<Integer> sub = new ArrayList<Integer>(); 
    perm2(sub, a);
}
public static void perm2(ArrayList<Integer> sub, ArrayList<Integer> a){
    int L = a.size();
    if (L==0) System.out.println(sub);
    else {
        System.out.println(sub);
        for (int i = 0; i < L; i++){
            sub.add(a.get(i));
            a.remove(i);
            perm2(sub, a);
            L = a.size(); // to avoid Index out of bounds exception
        }           
    }
}

这不会产生我希望的所有排列和组合。使用 arraylist [1, 2, 3],它只打印以下内容:

[]
[1]
[1, 2]
[1, 2, 3]

谁能告诉我如何修改 perm2 以便它打印其他预期值,例如 [2] [3] [2, 3] [3, 2] [2, 3, 1] [2, 1, 3] 等等...

【问题讨论】:

  • 什么是完整的期望输出?
  • 如果arraylist是{1,2,3},预期输出是{}, {1}, {2}, {3}, {1, 2}, {2, 1} , {1, 3}, {3, 1}, {2, 3}, {3, 2}, {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, { 2, 3, 1}, {3, 1, 2}, {3, 2, 1} - 顺序无关紧要

标签: java algorithm arraylist


【解决方案1】:

我强烈建议研究 Google 的 Guava 包:

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Collections2.html

这个包有一个非常有用的方法“permutations(Collection elements)”

这个包还包含“Sets”类中的“powerSet(Set set)”方法。 http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Sets.html

对 powerSet(Set) 和 permutations(Collection) 的嵌套调用应该会让事情变得非常简单。

【讨论】:

  • 我认为这应该是一个评论,因为它是对软件的建议。
【解决方案2】:

L=a.size() 的需要应该是一个提示。应保留 suba 值(它们的位置和值)以正常运行。

以下代码创建数组列表的新副本并对其进行操作:

public static void perm2(ArrayList<Integer> a) {
        ArrayList<Integer> sub = new ArrayList<Integer>();
        perm2(sub, a);
    }

 public static void perm2(ArrayList<Integer> sub, ArrayList<Integer> a) {
     int L = a.size();
     if (L == 0) System.out.println(sub);
     else {
         System.out.println(sub);
         for (int i = 0; i < L; i++) {
             ArrayList<Integer> ab = new ArrayList<Integer>(sub);
             ab.add(a.get(i));
             ArrayList<Integer> bc = new ArrayList<Integer>(a);
             bc.remove(i);
             perm2(ab, bc);
         }
     }
 }

【讨论】:

  • 这似乎在朝着正确的方向发展,但它给出了重复的元素 [1, 2, 3] [1, 2, 3] [2, 3, 1] [2, 3, 1] [2, 1, 3] [2, 1, 3]。我需要取消注释第二个 System.out.println(sub) 以返回较小的组合,如 [1] [2] [3] [1, 2] [1,3] 等。
  • 感谢 boxed__l - 这个解决方案非常适合我的需求!这是一个递归练习,所以它很昂贵并不重要......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2012-10-24
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多