排列 - 需要帮助设计一个不需要未使用值的更好的块

时间:2012-06-10 19:31:57

标签: java algorithm

我需要帮助通过手头丢弃不需要的排列来使我的排列(重要的,可重复的)大小更小。

  • 当前排列从提供的值中获取全局最小值和最大值。但是,之后的一些排列会被丢弃,因为它们不在所需的范围内。

  • 这个想法是例如需要排列的3个数字。例如:1-3,8-10和5-15。当前代码将创建1-15的排列,即使稍后将丢弃4-7的值。

不幸的是,在某些情况下,不可能在Java中创建足够大的数组来包含排列结果。

在计算排列之前,将此排列更改为仅包括必要值,将会有所帮助。

PermutationCore:

public class PermutationCore {
    private String[] a;
    private int n;

    public PermutationCore(String[] arrayOfPossibilities, int lengthOfPermutation) {
        this.a = arrayOfPossibilities;
        this.n = lengthOfPermutation;
    }

    public String[][] getVariations() {
        int l = a.length;
        int permutations = (int) Math.pow(l, n);

        Co.println("Permutation array size: " + permutations);

        String[][] table = new String[permutations][n];

        for (int x = 0; x < n; x++) {
            int t2 = (int) Math.pow(l, x);
            for (int p1 = 0; p1 < permutations;) {
                for (int al = 0; al < l; al++) {
                    for (int p2 = 0; p2 < t2; p2++) {
                        table[p1][x] = a[al];
                        p1++;
                    }
                }
            }
        }

        return table;
    }
}

置换

public class Permutation {
    private ArrayList<Iteration> listOfIteration = new ArrayList<Iteration>();
    private boolean prepared;
    private PermutationCore permutationCore;
    private int min = Integer.MAX_VALUE;
    private int max = Integer.MIN_VALUE;
    private int count = 0;
    private String[][] arrayOfStringResults;

    public void addIteration(Iteration iteration){
        if (prepared){throw new IllegalStateException("Permuation is already prepared. Create a new instance to add new items");}
        this.listOfIteration.add(iteration);
    }

    public void prepare(){
        String[] arrayOfString;

        for (Iteration iteration : listOfIteration){
            if (iteration.end > max){max = iteration.end;}
            if (iteration.start < min){min = iteration.start;}
        }

        arrayOfString = new String[max-min+1];

        for (int i=0; i<arrayOfString.length; i++){
            arrayOfString[i] = String.valueOf(min+i);
        }

        permutationCore = new PermutationCore(arrayOfString, listOfIteration.size());

        prepared = true;

//      Co.println("Min/max: " + min + "," + max);

        arrayOfStringResults = permutationCore.getVariations();
//      ArrayTools.sort2DStringArray(arrayOfStringResults);

    }

    public boolean iterate(){
        LABEL_ITERATE_LOOP: {
            int i=0;

            if (count == arrayOfStringResults.length){
                return false;
            }

            for (Iteration iteration : listOfIteration){
                int currentValue = Integer.valueOf(arrayOfStringResults[count][i]);

                if (currentValue > iteration.end || currentValue < iteration.start){
                    //Co.println("Failed at: " + iteration.start + "," + iteration.end + " / " + currentValue);
                    count++;
                    break LABEL_ITERATE_LOOP;
                }

                iteration.current = currentValue;
                i++;
            }

            count++;
        }

        return true;
    }

    public Iteration getIteration(Object request) {
        for (Iteration iteration : listOfIteration){
            if (iteration.request == request){
                return iteration;
            }
        }

        return null;
    }

    public ArrayList<Iteration> getListOfIterations(){
        return listOfIteration;
    }

    public static class Iteration{
        private int start;
        private int end;
        private int current;
        private Object request;

        public Iteration(int start, int end, Object request){
            this.start = start;
            this.end = end;
            this.request = request;
        }

        public double getCurrentValue(){
            return this.current;
        }

        public Object getRequest(){
            return this.request;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

这个问题是将k数从0到(n-1)排列,然后打印[n]而不是n。 :)这就是你可以做的,减少迭代。

另一种方法是使用介于0到n!-1之间的数字,找出当前的排列,然后打印出来。虽然这是一种较慢的方法,但以这种格式恢复操作会更快 - 我们可以快速打印第k个排列。

让我们说数字是:1,2,3,4。总共有4个!置换= 24,可能。要打印第15个(从零开始)排列,这就是我们的工作:

n = 4 a = 1 2 3 4 将15除以(n-1)!

我们得到15/6 = 2,提醒= 3。

所以排列以[2] = 3开始。

a = 1 2 4 接受提示,除以(n-2)!

我们得到3/2 = 1,提醒= 1。

所以排列现在是排列,a [1] = 3,2

a = 1 4 接受提示,除以(n-1)!

我们得到1/1 = 1,提醒= 0

所以排列现在是排列,a [1] = 3,2,4。

直到提醒为零。打印[0] = 3,2,4,1。

^这是生成任何系列的第k个排列的最有效方法。

您可以使用BigInteger数学来非常有效地执行此方法。