Java - ArrayList元素的排列组合(整数)- 无法正确运行

3

我已经花了很多时间来解决我的问题。 我解决了很多问题,但这个问题仍在困扰我:S。我已经很长时间没有接触Java编程(总的编程)了,所以请大家谅解! ;)

我的目标是从整数数组中获取所有可能的组合。 当我使用以下代码应用于测试整数数组{1,2,3,4}时,我希望得到:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
2 1 3 4
2 1 4 3
(...)
但是这就是我得到的结果:
1 2 3 4
1 2 3 4 4 3
1 2 3 4 4 3 3 2 4

有人有线索,建议或甚至解决方案吗?先感谢您!

public class Calculation{
(...)
  public void Permute(ArrayList<Integer> soFar,ArrayList<Integer> rest){
    if(rest.isEmpty())    this.fillMatrice(convertIntegers(soFar)); // there it goes in a previously created arrow of int
    else{
        for(int k=0;k<rest.size();k++){
            ArrayList<Integer> next=new ArrayList<Integer>();
            next=soFar;
            next.add(rest.get(k));
            ArrayList<Integer> remaining=new ArrayList<Integer>();
            List<Integer> sublist = rest.subList(0, k);
            for(int a=0;a<sublist.size();a++)   remaining.add(sublist.get(a));
            sublist = rest.subList(k+1,rest.size());
            for(int a=0;a<sublist.size();a++)   remaining.add(sublist.get(a));
            Permute(next,remaining);
        }
    }
}
public static ArrayList<Integer> convertArray(int[] integers){
    ArrayList<Integer> convArray=new ArrayList<Integer>();
    for(int i=0;i<integers.length;i++)  convArray.add(integers[i]);
    return convArray;
}
public static int[] convertIntegers(List<Integer> integers){
    int[] ret = new int[integers.size()];
    for(int i=0;i<ret.length;i++)   ret[i]=integers.get(i).intValue();
    return ret;
}
public Calculation() {
    (...)
    ArrayList<Integer> soFar=new ArrayList<Integer>();
    int[] test={1,2,3,4};
    Permute(soFar,convertArray(test));
}
2个回答

5

试试这个,它似乎可以工作,它使用递归。

public class Permute {

    public static List<List<Integer>> permute(Integer...myInts){

        if(myInts.length==1){
            List<Integer> arrayList = new ArrayList<Integer>();
            arrayList.add(myInts[0]);
            List<List<Integer> > listOfList = new ArrayList<List<Integer>>();
            listOfList.add(arrayList);
            return listOfList;
        }

        Set<Integer> setOf = new HashSet<Integer>(Arrays.asList(myInts));   

        List<List<Integer>> listOfLists = new ArrayList<List<Integer>>();

        for(Integer i: myInts){
            ArrayList<Integer> arrayList = new ArrayList<Integer>();
            arrayList.add(i);

            Set<Integer> setOfCopied = new HashSet<Integer>();
            setOfCopied.addAll(setOf);
            setOfCopied.remove(i);

            Integer[] isttt = new Integer[setOfCopied.size()];
            setOfCopied.toArray(isttt);

            List<List<Integer>> permute = permute(isttt);
            Iterator<List<Integer>> iterator = permute.iterator();
            while (iterator.hasNext()) {
                List<java.lang.Integer> list = iterator.next();
                list.add(i);
                listOfLists.add(list);
            }
        }   

        return listOfLists;
    }

    public static void main(String[] args) {
        List<List<Integer>> permute = permute(1,2,3,4);
        System.out.println(permute);
    }

}

如果您不喜欢List>,则可以使用来自列表(list)和静态方法(java.util.Collections和java.util.Arrays)的方法轻松地从数组更改到列表(list)。

谢谢,那也可以。不过Set、HashSet等我不熟悉,我很难理解其中的逻辑。 - Barbe Rouge
谢谢,这对我也有用。为了更好地理解您的逻辑,请问“_isttt_”变量名代表什么意思? - Laszlo Sisa
这个名称实际上并没有实际意义,它只是一个临时变量,用于在排列方法中再次传递。思路是:递归地选择每个数字,并将其与其他所有排列连接起来,直到子元素列表的长度为1。 - JayZee

2
您可以尝试使用“递归”来解决这个问题:
public static void printPermutations(int[] n, int[] Nr, int idx) {
    if (idx == n.length) {  //stop condition for the recursion [base clause]
        System.out.println(Arrays.toString(n));
        return;
    }
    for (int i = 0; i <= Nr[idx]; i++) { 
        n[idx] = i;
        printPermutations(n, Nr, idx+1); //recursive invokation, for next elements
    }
}

点击此链接可以获得更多信息:排列组合:生成所有“状态” - 数组组合

你也可以在这里复制相同的逻辑。


1
如果传入的数组大小非常大怎么办? - CPerkins
你的代码在n[i]从0到Nr[i]的所有可能方式中创建新的数组,但没有对现有的数组进行排列。但实际上这非常有用,因为我在Permutation方法中输入的数组来自先前计算的int[][],其中包含定义大小的int[],满足以下条件:
  • 其元素小于或等于Degree
  • 它们的总和等于Degree。
我的问题是要对创建的每个int[]中的所有整数进行排列。你的解决方案可以同时完成这两个任务。我只需要添加一个条件来测试数组中整数的总和是否等于Degree。
- Barbe Rouge
@user1503780,你可以根据需要修改代码。这只是一种伪代码,你可以这样说。 - UVM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接