Java 二维阵列列表的置换

Java 二维阵列列表的置换,java,arraylist,permutation,Java,Arraylist,Permutation,我试着制作一个二维数组列表,其中包含了所有可能的组合,比如1,2,3,4,递归。 没有双重身份 例如。 1,0,0 2,0,0 3,0,0 4,0,0 1,2,0 1,3,0 1,4,0 1,2,3 等等 到目前为止我有 //this gives me all my numbers for(int i =0;i<arraySize;i++) index[i] = i; // and is the part that make the combinations for(int i = 0;

我试着制作一个二维数组列表,其中包含了所有可能的组合,比如1,2,3,4,递归。 没有双重身份

例如。
1,0,0
2,0,0
3,0,0
4,0,0
1,2,0
1,3,0
1,4,0
1,2,3
等等

到目前为止我有

//this gives me all my numbers
for(int i =0;i<arraySize;i++)
index[i] = i;

// and is the part that make the combinations
for(int i = 0;i<arraySize;i++){
   for(int x = 0;x<k;x++)
      combinations.get(i).set(x, index[i]);
//这是我所有的号码

对于(int i=0;i<p>)你要查找的是什么。这个问题解决技术主要基于递归。基本上,你设置第一个数,然后只考虑其他数作为子问题,并且当每个排列都用第一个数集找到时,这个第一个数递增,等等。 您也可以使用直接的4 for循环来解决问题,但该解决方案不会扩展到4个数字以外的任何数字

public class PermutationDemo {

    public static void main(String[] args) {
        int[] array = new int[4];

        for (int i=0; i<array.length; i++) {
            reset(array, i);
        }

        solve(array, 0);
    }

    private static void solve(int[] array, int i) {
        if (i == array.length) {
            print(array);
            return;
        }

        for (int k=0; k<4; k++) {
            solve(array, i+1);
            makeMove(array, i);
        }

        reset(array, i);
    }

    private static void makeMove(int[] array, int i) {
        array[i] += 1;
    }

    private static void reset(int[] array, int i) {
        array[i] = 1;
    }

    private static void print(int[] array) {
        for (int i=0; i<array.length; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println("");
    }
}
您的解决方案如下所示。它将输出4个数字的每个排列

public class PermutationDemo {

    public static void main(String[] args) {
        int[] array = new int[4];

        for (int i=0; i<array.length; i++) {
            reset(array, i);
        }

        solve(array, 0);
    }

    private static void solve(int[] array, int i) {
        if (i == array.length) {
            print(array);
            return;
        }

        for (int k=0; k<4; k++) {
            solve(array, i+1);
            makeMove(array, i);
        }

        reset(array, i);
    }

    private static void makeMove(int[] array, int i) {
        array[i] += 1;
    }

    private static void reset(int[] array, int i) {
        array[i] = 1;
    }

    private static void print(int[] array) {
        for (int i=0; i<array.length; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println("");
    }
}

作为关于java中集合操作的一般提示,我建议您查看实用程序类,这些实用程序类为您完成了大部分繁重的工作,并确保您没有不了解的性能问题

然后,下一步是寻找一种适合您需要的方法。例如,可能就是您正在寻找的方法


最后,如果您希望自己将其作为算法练习来实现,您可以查看guava或Groove Collection API的源代码以获得想法。

另一个非递归选项。我使用“单词”表示(部分)排列,使用“符号”表示数字:

/**
 * Expands the set of existing words by adding non-repeated symbols to their right
 * @param symbols to choose from
 * @param existing words (may include the empty word)
 * @param expanded result 
 */
public static void expand(ArrayList<Integer> symbols, 
        ArrayList<ArrayList<Integer>> existing, 
        ArrayList<ArrayList<Integer>> expanded) {
    for (ArrayList<Integer> prev : existing) {
        Integer last = prev.isEmpty() ? null : prev.get(prev.size()-1);
        for (Integer s : symbols) {
            if (last == null || s > last) {
                ArrayList<Integer> toAdd = new ArrayList<>(prev);
                toAdd.add(s);
                expanded.add(toAdd);
            }
        }
    }
}

public static void main(String[] args) {

    ArrayList<Integer> symbols = new ArrayList<>(
            Arrays.asList(new Integer[]{1, 2, 3, 4}));

    ArrayList<ArrayList<Integer>> prev = new ArrayList<>();
    ArrayList<ArrayList<Integer>> next = new ArrayList<>();
    ArrayList<ArrayList<Integer>> aux;
    ArrayList<ArrayList<Integer>> output = new ArrayList<>();
    // add empty
    prev.add(new ArrayList<Integer>());
    // expand empty, then expand that expansion, and so on and so forth
    for (int i=0; i<symbols.size(); i++) {
        expand(symbols, prev, next);
        output.addAll(next);
        aux = prev; prev = next; next = aux;
        next.clear();
    }
    // print result (note: only for debugging purposes)
    for (ArrayList<Integer> o : output) {
        for (int i : o) System.out.print(i);  System.out.println();
    }
}

您有一个
ArrayList
并尝试获取其元素之间的所有排列?您想要一个“可能的组合,比如1,2,3,4”的列表,但在您的示例中,您已经放置了:1,0,0。由于0不在原始列表中,因此是否也不在输出中?:)@Sephy我有数组“索引”它是1,无论我的对象数组的长度是多少,我有一个组合,它是一个二维数组列表,我想用所有可能的“索引”组合来填充它@user2777005我想说的是我不想要111 112 113我需要1 2 3零应该是空的这似乎更像是一个计数器而不是一个排列——也就是说,你允许“1”或“12”这样的“不完整”字。是否允许使用“21”之类的词,或者你是在强制要求数字必须按递增顺序排列吗?这与我试图做的差不多,但在二维数组中,因为我需要将组合与对象数组的索引进行比较,以找到项目的最佳组合。请注意,可以调整展开规则以生成实际计数器(“所有单词,即使不完整,也包含允许的数字”)。我目前正在强制执行升序序列,因为提供的所有示例都是升序序列…这是我试图实现的结果。我希望所有这些组合都在二维数组或数组列表中,以便我可以单独使用这些值作为指向对象数组中的值索引的指针。
输出
ArrayList正是您要求的
output.get(rowIndex).get(colIndex)
生成与特定行/列索引对相对应的整数。请注意,并非所有行(=可能的组合)都具有相同的长度。
1
2
3
4
12
13
14
23
24
34
123
124
134
234
1234