com.github.azbh111.utils.java.math.permutation.FullPermutationGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-java Show documentation
Show all versions of utils-java Show documentation
com.github.azbh111:utils-java
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;
}
}
}