11

乱数を生成したいのですが、exclude配列から生成したくありません。これが私のコードです。

public int generateRandom(int start, int end, ArrayList<Integer> exclude) {
    Random rand = new Random();
    int range = end - start +1 - exclude.size();
    int random = rand.nextInt(range) + 1;

    for(int i = 0; i < exclude.size(); i++) {
        if(exclude.get(i) > random) {
            return random;
        }
      random++;
    }

    return random;
}

この関数をwhileループで使用し、各反復中に新しい値をに追加しますexclude。に属する番号を返す場合がありますexclude。どうしたの?

4

5 に答える 5

8

間違いがあると思います。

1)範囲はend-start + 1である必要があります。これは、必要な範囲だからです。
2)本当に乱数(コンピューター上で可能な限り「ランダム」)が必要な場合は、次に使用可能な番号を取得するだけではいけません。この場合、乱数は除外された数の密度/頻度の特性を持つためです。

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) {
    Random rand = new Random();
    int range = end - start + 1;
    int random;

    boolean success = false;
    while(!success) {
        random = rand.nextInt(range) + 1;
        for(Integer i: excludeRows) {
            if(i == random) {
                break;
            } else if (i > random) {
                success = true;
                break;
            }
        }
    }
    return random;
}

アップデート

Achintya Jhaの回答により、私のコードは改善される可能性があります(ただし、いくつかの注意事項もあることに注意してください)。

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) {
    Random rand = new Random();
    int range = end - start + 1;

    int random = rand.nextInt(range) + 1;
    while(excludeRows.contains(random)) {
        random = rand.nextInt(range) + 1;
    }

    return random;
}
于 2013-02-18T12:19:20.317 に答える
6
if(!exclude.contains(random))
    return random;

除外されていない値が返されるたびにこれを試してください。

于 2013-02-18T12:21:43.840 に答える
2

チェックします:

for(int i = 0; i < exclude.size(); i++) {
    if(exclude.get(i) > random) {
        return random;
    }

最初のものだけが大きい場合は、値を返します。excludeソートされていますか?

if(exclude.contains(random ))または次のアルゴリズムを使用できます。

(end-start)が妥当な数値であり、ほぼすべての値が必要な場合は、受け入れ可能なすべての数値のリストを作成し、このリストサイズでランダムを使用して、ランダムな値をインデックスとして選択できます。次に、リストから不要な番号を削除し、別のランダムなインデックスを取得します。

于 2013-02-18T12:13:24.333 に答える
1

これは私のために働いた:

    public int randomInt(int start, int end, int... exception) {
        int result = -1;
        Random rand = new Random();
        int range = end - start + 1;
        boolean equals = true;

        while(equals) {
            result = rand.nextInt(range);
            boolean differentOfAll = true;
            for(int i : exception) {
                if(result==i) {
                    differentOfAll = false;
                    break;
                }
            }
            if(differentOfAll) {
                equals = false;
            }
        }

        return result;
    }
于 2019-11-15T20:11:54.447 に答える
-1

contains(random)実際には、whileループで使用する必要はありません。

質問を単純化するために、除外値が1つしかない場合にどうなるかを見てみましょう。結果を2パーツに分割できます。その場合、可能な値の数はですrange-1。乱数が除外された値よりも小さい場合は、それを返すだけです。それ以外の場合は、を追加でき1ます。

複数の除外値の場合、結果セットをsize+1部分に分割できsizeます。これは、除外値の数を意味します。その場合、可能な値の数はですrange-size。次に、除外値を昇順で並べ替えます。乱数が除外値からを引いた値よりも小さい場合はi、乱数addを返します。iここiで、は除外値のインデックスです。

public int generateRandomNumberWithExcepts(int start, int end, List<Integer> excepts) {
    int size = excepts.size();
    int range = end - start + 1 - size;
    int randNum = random.nextInt(range) + start;
    excepts.sort(null); // sort excluding values in ascending order
    int i=0;
    for(int except : excepts) {
        if(randNum < except-i){
            return randNum + i;
        }
        i++;
    }
    return randNum + i;
}
于 2017-11-10T23:18:07.043 に答える