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

org.paukov.combinatorics3.DuplicatedPermutationIterator Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
/**
 * Combinatorics Library 3
 * Copyright 2009-2016 Dmytro Paukov [email protected]
 */
package org.paukov.combinatorics3;

import java.util.*;

class DuplicatedPermutationIterator implements Iterator> {

    final int length;

    List currentPermutation;
    long currentIndex = 0;

    private int data[] = null;
    private boolean firstIteration = true;
    private List initialOrderedPermutation;


    DuplicatedPermutationIterator(SimplePermutationGenerator generator) {

        length = generator.originalVector.size();
        data = new int[length];

        List originalVector = generator.originalVector;
        List initialPermutation = new ArrayList<>();

        // Create a set of the initial data
        Set initialSet = new LinkedHashSet<>(originalVector);

        // Create internal data
        int dataValue = 0;
        int dataIndex = 0;

        initialOrderedPermutation = new ArrayList<>(initialSet);

        for (T value : initialOrderedPermutation) {

            dataValue++;

            if (!initialPermutation.contains(value)) {
                // Determine how many duplicates of the value in the original
                // vector
                int count = intcountElements(originalVector, value);

                for (int countIndex = 0; countIndex < count; countIndex++) {
                    data[dataIndex++] = dataValue;
                    initialPermutation.add(value);
                }
            }
        }

        currentIndex = 0;
        currentPermutation = new ArrayList<>();

        for (int i = 0; i < length; i++) {
            int index = data[i] - 1;
            currentPermutation.add(initialOrderedPermutation
                    .get(index));
        }
    }


    @Override
    public boolean hasNext() {
        return !isFinished() || firstIteration;
    }


    @Override
    public List next() {

        if (firstIteration) {
            firstIteration = false;
            return currentPermutation;
        }

        int k = data.length - 2;

        while (data[k] >= data[k + 1]) {
            k--;
        }

        int l = data.length - 1;
        while (data[k] >= data[l]) {
            l--;
        }
        swap(data, k, l);
        int newlength = data.length - (k + 1);
        for (int i = 0; i < newlength / 2; i++) {
            swap(data, k + 1 + i, data.length - i - 1);
        }

        currentIndex++;
        currentPermutation = new ArrayList<>();

        for (int i = 0; i < length; i++) {
            int index = data[i] - 1;
            currentPermutation.add(initialOrderedPermutation
                    .get(index));
        }

        return currentPermutation;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }


    @Override
    public String toString() {
        return "DuplicatedPermutationIterator=[#" + (currentIndex + 1) + ", " + currentPermutation + "]";
    }

    private static void swap(int[] data, int k, int l) {
        int temp = data[k];
        data[k] = data[l];
        data[l] = temp;
    }

    private boolean isFinished() {
        int k = data.length - 2;
        while (data[k] >= data[k + 1]) {
            k--;
            if (k < 0) {
                return true;
            }
        }
        return false;
    }

    private static  int intcountElements(List list, T value) {
        int count = 0;
        for (T element : list) {
            if (element.equals(value))
                count++;
        }
        return count;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy