순열 알고리즘
배열의 모든 순열을 생성하려면 현재 배열부터 오름차순으로 시작하는 반복 접근 방식을 고려하세요. 목표는 하강 패턴을 깨는 요소를 교체하여 점진적으로 내림차순으로 변환하는 것입니다.
의사 코드 알고리즘
`
for (int tail = ind. 길이 - 꼬리 > 0; {
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!