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

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