首页 >Java >java教程 >如何使用 Java 中的迭代方法有效地生成数组的所有排列?

如何使用 Java 中的迭代方法有效地生成数组的所有排列?

Susan Sarandon
Susan Sarandon原创
2024-12-22 03:39:10506浏览

How can I efficiently generate all permutations of an array using an iterative approach in Java?

排列算法

要生成数组的所有排列,请考虑从当前数组开始按升序排列的迭代方法。目标是通过交换打破降序模式的元素,逐渐将其转换为降序。

伪代码算法

`
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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn