org.paukov.combinatorics3.MultiCombinationIterator Maven / Gradle / Ivy
/*
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.
*
* @param Type of the elements in the combinations.
* @author Dmytro Paukov
* @version 3.0
* @see MultiCombinationGenerator
*/
class MultiCombinationIterator implements Iterator> {
private final MultiCombinationGenerator generator;
private final List currentCombination = new ArrayList<>();
private final int[] bitVector;
private long currentIndex;
private boolean isEnd; // Criteria to stop iterating
MultiCombinationIterator(MultiCombinationGenerator generator) {
this.generator = generator;
this.bitVector = new int[generator.combinationLength];
for (int i = 0; i < generator.combinationLength; i++) {
bitVector[i] = 0;
}
this.isEnd = false;
this.currentIndex = 0;
}
private void setValue(int index, T value) {
if (index < this.currentCombination.size()) {
this.currentCombination.set(index, value);
} else {
this.currentCombination.add(index, value);
}
}
@Override
public boolean hasNext() {
return !isEnd;
}
@Override
public List next() {
this.currentIndex++;
if (this.bitVector.length == 0) {
this.isEnd = true;
return new ArrayList<>(this.currentCombination);
}
int size = this.generator.originalVector.size();
for (int i = 0; i < this.generator.combinationLength; i++) {
int index = bitVector[i];
if (size > 0) {
this.setValue(i, this.generator.originalVector.get(index));
}
}
int combinationLength = this.generator.combinationLength-1;
bitVector[combinationLength]++;
if (bitVector[combinationLength] > size - 1) {
int index = -1;
for (int i = 1; i <= bitVector.length; i++) {
if (combinationLength - i >= 0) {
if (bitVector[combinationLength - i] < size - 1) {
index = combinationLength - i;
break;
}
}
}
if (index != -1) {
this.bitVector[index]++;
for (int j = 1; j < this.bitVector.length - index; j++) {
this.bitVector[index + j] = this.bitVector[index];
}
} else {
this.isEnd = true;
}
}
// return a copy of the current combination
return new ArrayList<>(this.currentCombination);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return "MultiCombinationIterator=[#" + this.currentIndex + ", " + this.currentCombination + "]";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy