0

事前に不要な順列を破棄して、順列 (順序が重要で反復可能) のサイズを小さくするのに助けが必要です。

  • 現在の順列は、指定された値からグローバルな最小値と最大値を取ります。ただし、順列の一部は、必要な範囲内に収まらないため、後で破棄されます。

  • アイデアは、たとえば、順列が必要な3つの数字があるということです。例: 1-3、8-10、5-15。4 ~ 7 の値は後で破棄されますが、現在のコードでは 1 ~ 15 の順列が作成されます。

残念ながら、場合によっては、Java で並べ替えの結果を格納するのに十分な大きさの配列を作成できないことがあります。

順列を計算する前に、必要な値のみを含むようにこの順列を変更する際の助けをいただければ幸いです。

順列コア:

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;
        }
    }
}
4

1 に答える 1

3

これは、k 個の数値を 0 から (n-1) に並べ替え、n の代わりに a[n] を出力するという問題です。:) 繰り返しを減らすためにできることです。

もう 1 つの方法は、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 が得られます。

したがって、順列は a[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 になります。

リマインダーがゼロになるまで実行します。a[0]= 3, 2, 4, 1 を出力します。

^ これは、系列の k 番目の順列を生成する最も効率的な方法です。

BigInteger 数学を使用して、このメソッドを非常に効率的に実行できます。

于 2012-06-10T19:38:33.300 に答える