All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.azbh111.utils.java.math.permutation.FullPermutationGenerator Maven / Gradle / Ivy

The newest version!
package com.github.azbh111.utils.java.math.permutation;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * 1-n的n个数的全排列生成器
 * 每次迭代返回[0,n)的一个排列(每次返回的数组都是同一个对象,请自行拷贝)
 *
 * @author pyz
 * @date 2019/4/13 8:40 PM
 */
public class FullPermutationGenerator implements Iterable {

    private final int count;

    public FullPermutationGenerator(int n) {
        if (n < 0) {
            throw new IllegalArgumentException(n + "");
        }
        this.count = n;
    }

    public static Stream stream(int n) {
        return new FullPermutationGenerator(n).stream().parallel();
    }

    public Stream stream() {
        return StreamSupport.stream(this.spliterator(), false);
    }

    /**
     *
     * @return 若需要存储, 请自行拷贝, 然后在存储
     */
    @Override
    public Iterator iterator() {
        return new FullPermutationGeneratorIterator();
    }

    public class FullPermutationGeneratorIterator implements Iterator {

        private final int[] indexArr;
        private final int[] moveArr;
        /**
         * 调用hasNext后,会设置为true
         * 调用next后,会设置为false
         */
        private boolean cached = false;
        /**
         * 调用haxNext后,会确定这个的值
         */
        private int[] next;

        private FullPermutationGeneratorIterator() {
            indexArr = new int[count];
            moveArr = new int[count];
            for (int i = 0; i < count; ++i) {
                indexArr[i] = i;
                moveArr[i] = -1;
            }
            cached = true;
            next = indexArr;
        }

        private void swap(int[] intarr, int i, int j) {
            int temp;
            temp = intarr[i];
            intarr[i] = intarr[j];
            intarr[j] = temp;
        }

        @Override
        public boolean hasNext() {
            if (cached) {
                return next != null;
            }
            int i, j, t;
            //找到最大合法移动的元素索引
            for (i = count - 1, j = count; i >= 0; --i) {
                if (i + moveArr[i] < count && i + moveArr[i] >= 0 && indexArr[i] > indexArr[i + moveArr[i]]) {
                    if (j == count) {
                        j = i;
                        continue;
                    }
                    if (indexArr[i] > indexArr[j]) {
                        j = i;
                    }
                }
            }
            //未发现合法的移动策略
            if (j == count) {
                cached = true;
                next = null;
                return false;
            } else {
                t = indexArr[j];//要交换位置的元素
                i = j + moveArr[j];//发生交换的位置
                swap(indexArr, i, j);
                swap(moveArr, i, j);
                //将所有比t大的元素的移动方向反转
                for (i = 0; i < count; ++i) {
                    if (indexArr[i] > t) {
                        moveArr[i] = -moveArr[i];
                    }
                }
                cached = true;
                next = indexArr;
            }
            return next != null;
        }

        @Override
        public int[] next() {
            if (!cached) {
                hasNext();
            }
            cached = false;
            if (next == null) {
                throw new NoSuchElementException();
            }
            return next;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy