排列算法
要生成数组的所有排列,请考虑从当前数组开始按升序排列的迭代方法。目标是通过交换打破降序模式的元素,逐渐将其转换为降序。
伪代码算法
`
for (int tail = ind.长度 - 1; 尾部--) {
if (ind[tail - 1] < ind[tail]) { // still increasing // find last element that does not exceed ind[tail - 1] int s = ind.length - 1; while (ind[tail - 1] >= ind[s]) s--; swap(ind, tail - 1, s); // reverse order of elements in the tail for (int i = tail, j = ind.length - 1; i < j; i++, j--) swap(ind, i, j); break; }
}
`
实现
这是一个 Java 实现的示例,它处理不同的和重复的元素:
import java.util.Arrays; import java.util.Iterator; import java.lang.reflect.Array; class Permutations<E> implements Iterator<E[]> { private E[] arr; private int[] ind; private boolean has_next; public E[] output; // next() returns this array Permutations(E[] arr) { this.arr = arr.clone(); ind = new int[arr.length]; // convert an array of any elements into an array of integers Map<E, Integer> hm = new HashMap<>(); for (int i = 0; i < arr.length; i++) { Integer n = hm.get(arr[i]); if (n == null) { hm.put(arr[i], i); n = i; } ind[i] = n.intValue(); } Arrays.sort(ind); // start with ascending sequence of integers output = (E[]) Array.newInstance(arr.getClass().getComponentType(), arr.length); has_next = true; } public boolean hasNext() { return has_next; } public E[] next() { if (!has_next) { throw new NoSuchElementException(); } for (int i = 0; i < ind.length; i++) { output[i] = arr[ind[i]]; } // get next permutation has_next = false; for (int tail = ind.length - 1; tail > 0; tail--) { if (ind[tail - 1] < ind[tail]) { // still increasing // find last element that does not exceed ind[tail - 1] int s = ind.length - 1; while (ind[tail - 1] >= ind[s]) { s--; } swap(ind, tail - 1, s); // reverse order of elements in the tail for (int i = tail, j = ind.length - 1; i < j; i++, j--) { swap(ind, i, j); } has_next = true; break; } } return output; } private void swap(int[] arr, int i, int j) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } public void remove() { // not supported } }
示例
对于数组 [3, 4, 6, 2, 1],排列如下:
[3, 2, 1, 4, 6] [3, 2, 1, 6, 4] [3, 2, 4, 1, 6] [3, 2, 4, 6, 1] [3, 2, 6, 1, 4] [3, 2, 6, 4, 1] [3, 4, 1, 2, 6] [3, 4, 1, 6, 2] [3, 4, 2, 1, 6] [3, 4, 2, 6, 1] [3, 4, 6, 1, 2] [3, 4, 6, 2, 1] [3, 6, 1, 2, 4] [3, 6, 1, 4, 2] [3, 6, 2, 1, 4] [3, 6, 2, 4, 1] [3, 6, 4, 1, 2] [3, 6, 4, 2, 1] [4, 2, 1, 3, 6] [4, 2, 1, 6, 3] [4, 2, 3, 1, 6] [4, 2, 3, 6, 1] [4, 2, 6, 1, 3] [4, 2, 6, 3, 1] [4, 3, 1, 2, 6] [4, 3, 1, 6, 2] [4, 3, 2, 1, 6] [4, 3, 2, 6, 1] [4, 3, 6, 1, 2] [4, 3, 6, 2, 1] [4, 6, 1, 2, 3] [4, 6, 1, 3, 2] [4, 6, 2, 1, 3] [4, 6, 2, 3, 1] [4, 6, 3, 1, 2] [4, 6, 3, 2, 1] [6, 2, 1, 3, 4] [6, 2, 1, 4, 3] [6, 2, 3, 1, 4] [6, 2, 3, 4, 1] [6, 2, 4, 1, 3] [6, 2, 4, 3, 1] [6, 3, 1, 2, 4] [6, 3, 1, 4, 2] [6, 3, 2, 1, 4] [6, 3, 2, 4, 1] [6, 3, 4, 1, 2] [6, 3, 4, 2, 1] [6, 4, 1, 2, 3] [6, 4, 1, 3, 2] [6, 4, 2, 1, 3] [6, 4, 2, 3, 1] [6, 4, 3, 1, 2] [6, 4, 3, 2, 1]
以上是如何使用 Java 中的迭代方法有效地生成数组的所有排列?的详细内容。更多信息请关注PHP中文网其他相关文章!