0

ここで奇妙な状況が発生しました。あなたが私を助けてくれるかもしれないと思いました。1 から 10 までの数値が入力された int 配列があります。この配列から乱数を生成し、別の int 配列に保存したいと考えています。クラス Random を使用して任意の数字を選択し、ランダムに 0 をスローするので、そのように変更します (1 から 10 までの数字をスローします)。

randNum = rand.nextInt(numbers.length-min+1)+min;   

次のコードは、同じ乱数を生成する場合、それをスキップすることを確認します。プログラムは実際に動作しており、1 から 10 までのランダムに配置された別の配列を取得しています。それが私が望んでいたことです。しかし、時々私は 1 から 10 までの 1 つの数字を欠いていて、代わりに ZERO を取得しています。どうして??

int[] numbers = {1,2,3,4,5,6,7,8,9,10};
int[] usednum = new int[10];
Random rand = new Random();
int randNum;
int min = 1;

for (int x = 0; x<numbers.length; x++) {        
  for (int i = 0; i<usednum.length; i++) { 
    randNum = rand.nextInt(numbers.length-min+1) + min;
    for (int f = 0; f<usednum.length; f++) {
      if (usednum[f] == randNum) {
        break;
      } else if (usednum[f] == 0) { 
        usednum[x] = randNum;   
      }
    }
  } 
}

for (int c = 0; c<usednum.length; c++) {
  System.out.println(usednum[c]);
}
4

7 に答える 7

2

最も内側のforループは、現在の乱数がusednum[]配列内にあるかどうかのみをチェックします。そして、そのforすぐ外側のループは合計 10 回しかチェックしません。乱数を 10 個しか試行しないため、すぐにあきらめてしまいます。10 個すべてが既に使用されている場合、そのスロットには何も格納されませんusednum[](したがって、0になります)。その周りにループを追加してwhile、無関係な最も外側のループを取り除きforます。

        for(int i = 0; i<usednum.length; i++) {
           while(usednum[i]==0) {
              randNum = rand.nextInt(numbers.length-min+1)+min;
              for(int f = 0; f<usednum.length; f++) {
                 if(usednum[f] == randNum) {
                    break;
                 } //if                                                                                                                                        
                 else if (usednum[f] == 0) {
                    usednum[i] = randNum;
                 }
              }
           }
        }

また、割り当てが 用であることにも注意してくださいusednum[i] = randNum;

これは基本的に、中間forループ (i=0 から 9 までのループ) を while ループに置き換えています。

于 2012-08-31T14:22:52.693 に答える
2

単純に数値の配列をシャッフルすることが目的の場合は、代わりに次の方法を試してください。

Integer[] numbers = {1,2,3,4,5,6,7,8,9,10};
Collections.shuffle(Arrays.asList(numbers));

同じ効果があります。問題を手動で解決する必要がある宿題を完了する場合を除き、標準の Java ライブラリを使用してください。

このメソッドは、によって返される特別な型のおかげでshuffle、基になる配列に変更を書き込みます。notの配列を使用する必要があることに注意してください(なぜ Collections.shuffle() が配列で失敗するのですか? を参照してください)。IntegerListArrays.asList(...)Integerint

于 2012-08-31T14:19:21.930 に答える
0

実際には、配列のコンテンツを使用することはありませんnumbers。配列をのようなものに変更してみてくださいint[] numbers = { 10, 22, 23, 42, 53, 18, 7, 8, 93, 10 };。同様の出力が得られます。

Jon Linの回答は、コードが機能しない理由を説明していますが、この問題には対処していません。コードを次のようなものに変更することをお勧めします。

    int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int[] usednum = new int[10];
    Random rand = new Random();

    int selectedCount = 0;

    while (selectedCount < numbers.length) {
        int randNum = numbers[rand.nextInt(numbers.length)];
        boolean contains = false;
        for (int x = 0; x < selectedCount; x++) {
            if (usednum[x] == randNum) {
                contains = true;
                break;
            }
        }

        if (!contains) {
            usednum[selectedCount] = randNum;
            selectedCount++;
        }
    }


    for (int c = 0; c < usednum.length; c++) {
        System.out.println(usednum[c]);
    }
于 2012-08-31T14:29:05.827 に答える
0

for ループが多すぎます。

i イテレータを使用してループを削除すると、プログラムは必要な処理を実行するはずです。

ああ、乱数発生器から -min+1 を削除して、-1+1=0

于 2012-08-31T14:23:13.487 に答える
0

配列usednumは先頭がゼロで構成されています。場合によっては、プログラムはその初期値を変更せず、次の行の前で中断します。

if(usednum[f] == randNum)

同じ値を持つすべての反復中にそれを行いますxX増加し、ゼロ値を変更する機会があります。

于 2012-08-31T14:25:26.697 に答える
0

パス全体で使用される数値を生成しているため、ゼロは生成されず、本来あるべき値の生成に失敗するだけです。

于 2012-08-31T14:17:52.177 に答える
0

編集-それに従って、書き直しました:

List<Integer> numbers = new LinkedList<Integer>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }));
        int[] usednum = new int[10];
        Random rand = new Random();
        int n = numbers.size();
        for (int i = 0; i < n; i++) {
            int randNum = rand.nextInt(numbers.size());
            usednum[i]=numbers.get(randNum);
            numbers.remove(randNum);
        }
        for (int c:usednum) {
            System.out.println(c); 
        }
于 2012-08-31T14:13:38.160 に答える