如何将所有数组置换迭代地返回到二维数组中?

时间:2019-06-17 12:23:11

标签: java arrays string permutation

我正在尝试编写一个程序,该程序将遍历String数组的所有可能排列,并返回具有所有排列的二维数组。具体来说,我尝试使用长度为4的String数组返回具有24行4列的2D数组。

我只找到了迭代打印字符串的方法,但没有在数组中使用它们。我还发现了递归的方法,但是它们不起作用,因为我正在与其他人一起使用此代码,并且递归函数要困难得多。

对于我想要的代码,我知道标题应该是:

SELECT C.CustomerName,T.TransactionsSum,A.AdditionsSum FROM `customers` AS C 
LEFT JOIN (SELECT customerID,sum(T1.price) AS TransactionsSum FROM sites AS S 
        LEFT JOIN transactions AS T1 ON S.id = T1.site
        GROUP By S.customerID) AS T ON C.id = T.customerID
LEFT JOIN (SELECT customerID,sum(A1.price) AS AdditionsSum FROM sites AS S 
        LEFT JOIN additions AS A1 ON S.id = A1.site
        GROUP By S.customerID) AS A ON C.id = A.customerID

///我尝试将递归方法与堆算法结合使用,但是它的参数非常复杂。

我对编程非常陌生,任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您的排列问题基本上只是一个索引排列问题。 如果您可以对所有可能的变体中的数字从0到n-1进行排序,则可以将它们用作输入数组的索引,只需复制字符串即可。以下算法不是最佳算法,但是它的图形足以解释和迭代实现。

public static String[][] getAllPermutations(String[] str) {
    LinkedList<Integer> current = new LinkedList<>();
    LinkedList<Integer[]> permutations = new LinkedList<>();

    int length = str.length;
    current.add(-1);

    while (!current.isEmpty()) {
        // increment from the last position.
        int position = Integer.MAX_VALUE;
        position = getNextUnused(current, current.pop() + 1);
        while (position >= length && !current.isEmpty()) {
            position = getNextUnused(current, current.pop() + 1);
        }
        if (position < length) {
            current.push(position);
        } else {
            break;
        }

        // fill with all available indexes.
        while (current.size() < length) {
            // find first unused index.
            int unused = getNextUnused(current, 0);

            current.push(unused);
        }
        // record result row.
        permutations.add(current.toArray(new Integer[0]));
    }

    // select the right String, based on the index-permutation done before.
    int numPermutations = permutations.size();
    String[][] result = new String[numPermutations][length];
    for (int i = 0; i < numPermutations; ++i) {
        Integer[] indexes = permutations.get(i);
        String[] row = new String[length];
        for (int d = 0; d < length; ++d) {
            row[d] = str[indexes[d]];
        }
        result[i] = row;
    }

    return result;
}

public static int getNextUnused(LinkedList<Integer> used, Integer current) {
    int unused = current != null ? current : 0;
    while (used.contains(unused)) {
        ++unused;
    }
    return unused;
}

getAllPermutations方法组织在初始化部分中,该循环收集所有排列(数字),最后将找到的索引排列转换为String-permutations。

由于从int到String的转换是微不足道的,所以我只解释集合部分。只要表示未完全耗尽或从内部终止,循环就会重复进行。

首先,我们增加表示形式(current)。为此,我们取最后一个“数字”并将其递增到下一个自由值。然后,如果超出长度,则弹出,然后查看下一位(并将其递增)。我们将继续执行此操作,直到达到合法值(长度小于一)。

此后,我们用剩余的所有数字填充剩余的数字。完成后,我们将当前表示形式存储到数组列表中。

就运行时间而言,此算法并非最佳!堆更快。但是,迭代地实现Heap需要一个不平凡的堆栈,难以实现/解释。