org.paukov.combinatorics3.MultiCombinationIterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of combinatoricslib3 Show documentation
Show all versions of combinatoricslib3 Show documentation
Combinatorial objects stream generators for Java.
/**
* Combinatorics Library 3
* Copyright 2009-2016 Dmytro Paukov [email protected]
*/
package org.paukov.combinatorics3;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Multi-combinations iterator for enumerating combinations with repetitions
*
* @author Dmytro Paukov
* @see MultiCombinationGenerator
* @param
* Type of the elements of the combinations
* @version 3.0
*/
class MultiCombinationIterator implements
Iterator> {
private final MultiCombinationGenerator generator;
private List currentCombination = null;
private long currentIndex = 0;
private final int lengthN;
private final int lengthK;
private int[] bitVector = null;
// Criteria to stop iterating
private boolean end = false;
MultiCombinationIterator(MultiCombinationGenerator generator) {
this.generator = generator;
lengthN = generator.originalVector.size();
currentCombination = new ArrayList<>();
bitVector = new int[generator.combinationLength];
lengthK = generator.combinationLength - 1;
for (int i = 0; i < generator.combinationLength; i++) {
bitVector[i] = 0;
}
end = false;
currentIndex = 0;
}
@Override
public boolean hasNext() {
return (!end);
}
@Override
public List next() {
currentIndex++;
for (int i = 0; i < generator.combinationLength; i++) {
int index = bitVector[i];
if (generator.originalVector.size() > 0) {
setValue(currentCombination, i, generator.originalVector
.get(index));
}
}
if (bitVector.length > 0) {
bitVector[lengthK]++;
if (bitVector[lengthK] > lengthN - 1) {
int index = -1;
for (int i = 1; i <= bitVector.length; i++) {
if (lengthK - i >= 0) {
if (bitVector[lengthK - i] < lengthN - 1) {
index = lengthK - i;
break;
}
}
}
if (index != -1) {
bitVector[index]++;
for (int j = 1; j < bitVector.length - index; j++) {
bitVector[index + j] = bitVector[index];
}
} else {
end = true;
}
}
} else {
end = true;
}
// return a copy of the current combination
return new ArrayList<>(currentCombination);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return "MultiCombinationIterator=[#" + currentIndex + ", " + currentCombination + "]";
}
private static void setValue(List list, int index, T value) {
if (index < list.size()) {
list.set(index, value);
} else {
list.add(index, value);
}
}
}