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

de.invation.code.toval.math.Permutations Maven / Gradle / Ivy

package de.invation.code.toval.math;

import java.math.BigInteger;
import java.util.Iterator;

/**
 * Permutation Generator.
 * Generates all permutations of an array with a specified length.
 */
public abstract class Permutations implements Iterator{

	/**
	 * Array holding different permutations.
	 */
	private Integer[] position;
	/**
	 * Number of permutations left (not yet generated).
	 */
	private BigInteger permLeft;
	/**
	 * Total number of permutations.
	 */
	private BigInteger permTotal;

	/**
	 * Initializes the permutation generation mechanism using the specified length,
	 * which is interpreted as the number of elements that are permuted.
	 * @param elementNumber Number of elements to permute.
	 */
	public Permutations(int elementNumber) {
		if (elementNumber < 1)
			throw new IllegalArgumentException("Illegal length: "+elementNumber);
		position = new Integer[elementNumber];
		permTotal = getFactorial(elementNumber);
		reset();
	}

	/**
	 * Resets the permutation generator.
	 */
	public void reset() {
		for (int i = 0; i < position.length; i++) {
			position[i] = i;
		}
		permLeft = new BigInteger(permTotal.toString());
	}

	/**
	 * Returns the residual number of permutations.
	 * @return Residual number of permutations
	 */
	public BigInteger getNumLeft() {
		return permLeft;
	}

	/**
	 * Returns the total number of permutations.
	 * @return Total number of permutations
	 */
	public BigInteger getTotal() {
		return permTotal;
	}

	/**
	 * Checks if there are residual permutations.
	 * @return true if there are residual permutations;
	 * false otherwise
	 */
	public boolean hasNext() {
		return permLeft.compareTo(BigInteger.ZERO) == 1;
	}

	/**
	 * Computes the factorial of the given number
	 * @param number jBasic number for factorial computation
	 * @return The factorial of number
	 */
	private static BigInteger getFactorial(int number) {
		BigInteger factorial = BigInteger.ONE;
		for (int i = number; i > 1; i--) {
			factorial = factorial.multiply(new BigInteger(Integer.toString(i)));
		}
		return factorial;
	}

	/**
	 * Generates the next permutation (algorithm from Rosen p. 284)
	 * @return an array containing the next permutation
	 */
	public Integer[] nextPermutation() {
		if (permLeft.equals(permTotal)) {
			permLeft = permLeft.subtract(BigInteger.ONE);
			return position;
		}
		
		// Find largest index j with a[j] < a[j+1]
		int j = position.length - 2;
		while (position[j] > position[j + 1]) { j--;}

		// Find index k such that a[k] is smallest integer
		// greater than a[j] to the right of a[j]
		int k = position.length - 1;
		while (position[j] > position[k]) { k--;}

		// Interchange a[j] and a[k]
		int temp;
		temp = position[k];
		position[k] = position[j];
		position[j] = temp;

		// Put tail end of permutation after j-th position in increasing order
		int r = position.length - 1;
		int s = j + 1;
		while (r > s) {
			temp = position[s];
			position[s] = position[r];
			position[r] = temp;
			r--;
			s++;
		}
		
		permLeft = permLeft.subtract(BigInteger.ONE);
		return position;
	}

	/**
	 * This Iterator-implementation does not support the optional remove-operation.
	 */
	@Override
	public void remove() {
		throw new UnsupportedOperationException();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy