从锯齿状阵列的每一行添加元素

时间:2013-07-21 23:24:12

标签: java arrays permutation jagged-arrays

我试图通过每行只使用一个元素来获取n行,锯齿状的2d字符串数组中的每个元素组合。

示例数组(每行代表数组中的一行):

“A”, “B”, “C”

“d”, “E”

“F”, “G”, “H”, “I”, “J”

对于上述阵列,将有30种可能的组合。我们欢迎递归解决方案,但出于内存使用原因,我更倾向于迭代解决方案。

3 个答案:

答案 0 :(得分:0)

如果n是变量,我想不出任何针对您的问题的迭代解决方案。

递归解决方案:

ArrayList<String> permutations = new ArrayList<String>();
generatePermutations ("", 0);

/** Where the function generatePermutations is defined as: **/

void generatePermutations (String s, int index) {
    if (index >= n) {
        permutations.add(s);
        return;
    }
    for (String a : myJaggedArray[index]) {
        generatePermutations (s + a, index + 1)
    }
}

答案 1 :(得分:0)

这应该处理任何大小的锯齿状阵列,但我只测试了大约5个案例。

我们的基本策略是使用数组来跟踪我们将从子数组接下来获得的元素的当前索引,并且一旦我们将序列放入permutationArray中,我们将增加最右边的索引。如果该索引等于最右边的子阵列的大小,那么我们将最右边的索引设为0并增加第二个到最右边的索引。如果该索引等于该子数组的大小,我们将该索引设为0并增加先前的索引。这个过程向下冒泡到第一个索引,直到我们没有更多的排列。

    char list[][] = new char[][] { { 'a', 'b', 'c' }, { 'd', 'e' },
            { 'f', 'g', 'h', 'i', 'j' } };

    int permutations = 1;
    for (int i = 0; i < list.length; ++i)
        permutations *= list[i].length;

    char permutationArray[][] = new char[permutations][list.length];

    // list of lengths of each subarray
    int listlength[] = new int[list.length];
    for (int i = 0; i < list.length; ++i)
        listlength[i] = list[i].length;

    // traverse list in a permutation, once this gets to the length then we
    // increase indicies starting from the right side
    int listindicies[] = new int[list.length];

    for (int i = 0; i < permutations; ++i) {
        for (int j = 0; j < list.length; ++j) {
            permutationArray[i][j] = list[j][listindicies[j]];

            if (j == (list.length - 1))
                listindicies[j]++;
        }

        // reset indicies if they are equal to the length of the array
        for (int k = list.length - 1; k >= 0; --k) {
            if (listindicies[k] == (listlength[k])) {
                listindicies[k] = 0;
                if (k != 0)
                    listindicies[k - 1]++;
            } else {
                break;
            }
        }

    }

    for (int i = 0; i < permutationArray.length; ++i) {
        for (int j = 0; j < permutationArray[i].length; ++j)
            System.out.print(permutationArray[i][j] + " ");
        System.out.println("");
    }

答案 2 :(得分:0)

这是一个使用modulo的有趣小方法:

public static void main(String args[]) {
    iterate(new String[][]{{"a","b","c"},{"d","e"},{"f","g","h","i"}});
}
static void iterate(String[][] jagged) {
    int count = 1;
    int[] divisors = new int[jagged.length];
    for (int j = 0; j < jagged.length; j++) {
        divisors[j] = count;
        count *= jagged[j].length;
    }
    for (int i = 0; i < count; i++) {
        String[] combination = new String[jagged.length];
        for (int j = 0; j < jagged.length; j++) {
            int mod = jagged[j].length;
            combination[j] = jagged[j][(i/divisors[j])%mod];
        }
        process(combination);
    }
}
static void process(String[] combination) {
    System.out.println(Arrays.toString(combination));
    // Do whatever you want here. Process as you go to save memory,
    // or add to a list to process later.
}

它的核心是combination[j] = jagged[j][(i/divisors[j])%mod]; divisors[j]是早期长度的乘积,即使用较低索引数组可能的组合数。 mod是当前数组的长度。

如果您反对最后一个元素更快地迭代而第一个元素更慢,则在计算divisors / count时反转顺序,即从j开始计算jagged.length {{1}}为0。