如何将return所有数组排列迭代到two-dimensional数组中?
How to return all array permutations iteratively into a two-dimensional array?
我正在尝试编写一个程序来遍历字符串数组的所有可能排列,return 一个包含所有排列的二维数组。具体来说,我正在尝试使用长度为 4 的字符串数组 return 具有 24 行和 4 列的二维数组。
我只找到了迭代打印字符串但没有在数组中使用它们的方法。我也找到了递归的方法,但它们不起作用,因为我正在与其他人一起使用这段代码,而递归函数要困难得多。
对于我希望代码执行的操作,我知道 header 应该是:
public class Permutation
{
public String[][] arrayPermutation(String[] str)
{
//code to return 2D array
}
}
//我尝试使用堆算法的递归方法,但是//它的参数非常复杂。
我是编程新手,非常感谢任何帮助。
你的 permutation-problem 基本上只是一个 index-permutation 问题。
如果您可以在所有可能的变体中对从 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-method 组织在初始化部分,循环收集所有排列(数字),最后将找到的 index-permutation 转换为 String-permutations.
由于从 int 到 String 的转换很简单,我将只解释集合部分。只要表示没有完全耗尽或从内部终止,循环就会迭代。
首先,我们增加表示(current
)。为此,我们采用最后一个 'digit' 并将其递增到下一个自由值。然后我们弹出,如果我们超过长度,并查看下一个数字(并增加它)。我们继续这样做,直到我们达到合法值(低于长度)。
之后,我们用所有剩余的数字填充剩余的数字。完成后,我们将当前表示存储到数组列表中。
这个算法在运行时间上不是最优的!堆更快。但是迭代地实现堆需要一个 non-trivial 堆栈,这对 implement/explain.
来说很烦人
我正在尝试编写一个程序来遍历字符串数组的所有可能排列,return 一个包含所有排列的二维数组。具体来说,我正在尝试使用长度为 4 的字符串数组 return 具有 24 行和 4 列的二维数组。
我只找到了迭代打印字符串但没有在数组中使用它们的方法。我也找到了递归的方法,但它们不起作用,因为我正在与其他人一起使用这段代码,而递归函数要困难得多。
对于我希望代码执行的操作,我知道 header 应该是:
public class Permutation
{
public String[][] arrayPermutation(String[] str)
{
//code to return 2D array
}
}
//我尝试使用堆算法的递归方法,但是//它的参数非常复杂。
我是编程新手,非常感谢任何帮助。
你的 permutation-problem 基本上只是一个 index-permutation 问题。 如果您可以在所有可能的变体中对从 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-method 组织在初始化部分,循环收集所有排列(数字),最后将找到的 index-permutation 转换为 String-permutations.
由于从 int 到 String 的转换很简单,我将只解释集合部分。只要表示没有完全耗尽或从内部终止,循环就会迭代。
首先,我们增加表示(current
)。为此,我们采用最后一个 'digit' 并将其递增到下一个自由值。然后我们弹出,如果我们超过长度,并查看下一个数字(并增加它)。我们继续这样做,直到我们达到合法值(低于长度)。
之后,我们用所有剩余的数字填充剩余的数字。完成后,我们将当前表示存储到数组列表中。
这个算法在运行时间上不是最优的!堆更快。但是迭代地实现堆需要一个 non-trivial 堆栈,这对 implement/explain.
来说很烦人