0

引数で渡された数値を除いて、1から54までの乱数を返すメソッドを書くための宿題があります。メソッドヘッダーは次のように指定されます。

public static int getRandom(int... numbers)

一次元配列よりも高度なものは使用できません。

私のコードは:

public class PE13RandomNumberChooserVer2 {

    public static void main(String[] args) {

        int[] excludeNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18};
        int randomNumber = getRandom(excludeNumbers);
        System.out.println();
        System.out.println("Random number chosen: " + randomNumber);
    }

    public static int getRandom(int... excludeNumbers) {

        int random = 1 + (int)(Math.random() * (54 - 1) + 1);
        System.out.println("Numbers to exclude: ");

        for (int i = 0; i < excludeNumbers.length; i++) {
            System.out.print(excludeNumbers[i] + " ");
            while (excludeNumbers[i] == random) {
                random = 1 + (int)(Math.random() * 54);
                System.out.println("\n(for test only) next random number: " + random);
            }
        }

        return random;
    }

}

サンプル実行は、私のロジックが間違っていることを示しました:

(for test only) initial random number: 8
Numbers to exclude: 
1 2 3 4 5 6 7 8 
(for test only) next random number: 12
11 12 
(for test only) next random number: 3
13 14 15 16 17 18 
Random number chosen: 3

ランダムが配列内の現在の項目と等しいかどうかのみをチェックし、すでにチェックされているリスト内の前の項目と等しい場合は考慮しません。

ランダムに生成された数値の最終結果は、配列内の数値とは異なる値になるはずです。それを修正する方法の提案は大歓迎です。

4

8 に答える 8

4

以下はそれを行います:

    private final Random rand = new Random();

    public int getRandom(int min, int max, int... excludeNumbers) {
        int random = rand.nextInt(max - min + 1 - excludeNumbers.length) + min;
        for (int exc : excludeNumbers) {
            if (random >= exc) {
                random++;
            }
        }
        return random;
    }

単一の乱数のみを生成し、拒否ループを必要としない方法を観察してください。

minとは両方を含むことに注意してくださいmaxexcludeNumbersまた、昇順で表示する必要があることに注意してください。

于 2012-12-16T19:26:36.690 に答える
3

これ

int random = 1 + (int)(Math.random() * (54 - 1) + 1);

この

random = 1 + (int)(Math.random() * 54);

は奇妙で、一致するはずです。

後者が正しい。

次に、ループが間違っています。ループは、禁止された番号と一致した場合に番号を再生成するためのものです。したがって、すべてのループのfor内側whileと外側に配置する必要があります。生成された 1 つの禁止番号をすべてチェックするように機能し、再試行ループとしてサーバーに送信する必要があります。printlnforwhile

また、 Random クラスを使用することもできます。

コード

public static void main(String[] args) {

        int[] excludeNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18};
        int randomNumber;

        System.out.println("Numbers to exclude: ");
        for (int i = 0; i < excludeNumbers.length; i++) {
            System.out.print(excludeNumbers[i] + " ");
        }


        // 100 tests
        for(int i=0; i<100; ++i ) {


            randomNumber = getRandom(excludeNumbers);
            System.out.println();
            System.out.println("Random number chosen: " + randomNumber);
        }
    }

    public static int getRandom(int... excludeNumbers) {

        int random;



        // regeneration loop 
        regeneration: while(true) {

            // generating a number
            random = 1 + (int)(Math.random() * 54);

            // checking of it's correctness
            for (int i = 0; i < excludeNumbers.length; i++) {

                // checking if number conincides for prohibited
                if( excludeNumbers[i] == random ) {

                    // if number concided, then going to regeneration
                    continue regeneration;
                }

                // here number has not coincided 
                // but with just one of prohibites
                // no decision here
            }

            // here all prohibited numbers checked and 
            // no coincidences found
            // so generated number is good

            System.out.println("\n(for test only) next random number: " + random);
            break regeneration;

        } 

        return random;
    }
于 2012-12-16T19:07:39.230 に答える
1

許可された数に達するまで再試行を続けるテクニックは粗雑であり、許可された数が1に近づくと、泣き叫ぶ悲惨に変わります。はるかにエレガントな方法は次のとおりです。

  1. boolean[54];を作成します。
  2. 除外された各要素をtrue;に設定します。
  3. 許可された選択肢の数(54-除外の数)と同じ大きさの範囲から乱数rを選択します。
  4. ブール配列のr番目のfalse要素を返します。

boolean注:このアルゴリズムは、配列をキャッシュできる場合に最適です。正確なケースでは(関数は毎回新しい配列を受け取ります)、NPEのソリューションが優れています。

于 2012-12-16T19:27:51.117 に答える
1

これを試してみてください。許容できる数になるまで試行を続けます。

List<Integer> nums = Arrays.asList(excludedNumbers);
while (true) {
    Random random = 1 + (int)(Math.random() * 54);
    if (!nums.contains(random))
        return random;
}

除外番号をリストとして渡した場合、メソッドはよりクリーンになります。

于 2012-12-16T19:06:14.540 に答える
0

パブリック クラス コンピュート {

public static void main(String[] args) {
    int[] values = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41};
    int x = 1+ (int) (Math.random()*54);
    System.out.println("Value: "+getRandom(x,values));  
}

public static int getRandom(int a, int... numbers){

    System.out.println("x1: "+a);
    for(int j=0;j<numbers.length;){
        //System.out.println("Numbers: "+numbers[j]);
        if(numbers[j]==a){
            a = 1 + (int) (Math.random()*54);
            System.out.println("x2: "+a);
            j=0;
            continue;
        }
        j++;
    }
    return a;

}

}

于 2015-08-21T06:41:43.017 に答える
0
public static int getRandom(int... numbers) {
    final Random random = new Random();
    final int[] arr1 = new int[54];
    int count = 54;
    for(int i = 0; i < arr1.length; ++i) {
        arr1[i] = i + 1; // good luck doing this with foreach
    }
    for(int i = 0; i < numbers.length; ++i) {
        final int n = numbers[i];
        if(arr1[n] != 0) {
            --count;
        }
        arr1[n] = 0;
    }
    final int[] arr2 = new int[count];
    for(int i = 0, j = 0; i < arr2.length; ++i, ++j) {
        if(arr1[j] == 0) {
            ++j;
        }
        else {
            arr2[i] = arr1[j];
        }
    }
    return arr2[random.nextInt(count)];
}
于 2015-08-01T13:34:36.473 に答える
0

私も今Javaを独学しています。オンラインでまだ回答が得られていない間、私はすでにこの問題に数日を費やしています. 上記の解決策は、これまでのところ私にとっては高度すぎます。これが最終的に私の解決策です。これは基本的な配列の知識のみを採用しています

    public class Q6_13 {
    public static void main(String[] args)  {
        int[] excludeNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18};
        System.out.println (getRandom(excludeNumbers));
    }

    public static int getRandom(int...numbers)  {
        int n =  (int)(Math.random() * 54) + 1; ;
        boolean newRandom = false;
        boolean getNew = false;

         while (getNew == false)   {
        for (int i = 0; (i < numbers.length) && newRandom == false; i++)    {
            if (n == numbers[i])    {
                newRandom = true;                 
            }
        }
            if (newRandom)  {
                n = (int)(Math.random() * 54) + 1; 
                getNew = false;
                newRandom = false;
            }
            else
                getNew = true;
        }
        return n;
    }
}
于 2013-04-01T19:18:14.980 に答える
0

java.util.random を調べてください。0 から指定した数値までのランダムな整数を提供するメソッドがあります。現時点ではこれを携帯電話から入力しているため、例を挙げることはできませんが、1 から 54 の間で取得する場合は、0 から 53 の間の乱数を取得し、結果に 1 を加算します。

于 2012-12-16T20:35:37.857 に答える