• ベストアンサー

JAVA 乱数で同じ数字を出さない方法

JAVAで乱数を使いたいのですが、同じ数を出さない方法が今一度 わかりません。 プログラムはサーブレットで記述しており、ブラウザで「数を出す」ボタンがおされたら、リクエストを受けたサーブレットは、一つ、1~10までの数を出し表示はJSPです。そしてまたボタンが押されたら、一つ、1~10までの数を出します。 以下に今のサーブレットに記述してあるプログラムの状態を書かせていただきますので、同じ数字を出さない方法が何かございましたら教えてください。宜しくお願いします。 long seed = System.currentTimeMillis(); //時間で乱数値をとる Random r1=new Random(seed); //乱数ジェネレータを作成する int i; i = r1.nextInt(10)+1;//入力された命令回数をint型に変換し1から10までの数が出されiに入る。

  • Java
  • 回答数6
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
noname#119918
noname#119918
回答No.5

もちろんIteratorによる順次アクセスも可能です。 先ほどの例に続けると、下記の様になるでしょうか。 import java.util.Random; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; // 追加部分 class Test { public static void main(String [] args) { ArrayList<Integer> list = new ArrayList<Integer>(); for(int i=0 ; i<10 ; i++) { list.add(i); } System.out.println(list); Collections.shuffle(list , new Random()); System.out.println(list); // 追加部分 Iterator<Integer> it = list.iterator(); while(it.hasNext()) { System.out.print(it.next() + " "); } System.out.println(); } }

aabbccddzz
質問者

補足

なるほど。あの変な質問ですが・・・もしなんですが、サーブレットでこのような定義をしたら、リクエストがあるたびにまたいちから数値をランダムにして取り出すので、同じ数字がでてしまいますよね。?恐らくそのようになると思うのですが・・・・。

その他の回答 (5)

noname#119918
noname#119918
回答No.6

>なるほど。あの変な質問ですが・・・もしなんですが、サーブレットでこのような定義をしたら、リクエストがあるたびにまたいちから数値をランダムにして取り出すので、同じ数字がでてしまいますよね。?恐らくそのようになると思うのですが・・・・。 そうですね。そうなると思います。 私はサーブレットは詳しくないので、サーブレットでどのような手法を用いるのが適切かはわかりませんが、 一般論としては乱数列をあらかじめファイルなどに用意しておき、 リクエストがあるたびにファイルから乱数を取り出し、 消費した乱数を消去する、というような手順をとることになるかと思います。

aabbccddzz
質問者

お礼

なるほど。確かにそのようにも考えられますね。 わかりました。皆様からのアドバイスをもとに、もう少し考え、まとめてみます。恐らく、サーブレットとモデル両方で試してみる必要もあるかと思いますので。モデルで考える際には、あなた様のご回答の例プログラムを参考にさせていただきたいと思っております。 この度は、ご親切なご回答誠にありがとうございます。 とても助かりました。 あなた様を含め、ここでご回答して下さった方々には大変感謝しております。 ここ数日間、様々な方にアドバイスを頂きお世話になっております。 私は幸せ者です。今後も、何卒宜しくお願い申し上げます。

noname#119918
noname#119918
回答No.4

rancoさんのおっしゃているやり方を使用した場合の簡単な例です。 1~9までの数字をリストに用意し、シャッフルして乱数列とします。 import java.util.Random; import java.util.ArrayList; import java.util.Collections; class Test { public static void main(String [] args) { ArrayList<Integer> list = new ArrayList<Integer>(); for(int i=0 ; i<10 ; i++) { list.add(i); } System.out.println(list); Collections.shuffle(list , new Random()); System.out.println(list); } }

aabbccddzz
質問者

補足

あ、ありがとうございます。突然素晴らしい回答をして下さったので、驚き、言葉がでませんでした。とても助かりました。 あの、もう一つお聞きしたいのですが、listの先頭からひとつ 取り出すのはiteratorでせきると思うのですが・・・・できますよね? あ、でも、iteratorを使うと次々に入っている数字が出てしまいますよね?ここのところを、もしよろしければ教えていただけませんでしょうか?

  • nak777r
  • ベストアンサー率36% (49/136)
回答No.3

サーブレット という事は WEBですよね 10人がアクセスしたら、10人に違う数値を出せと言うことですか? 11人がアクセスしたら無理なので違うのかな 同じ人(ブラウザ)が、10回、数を出すボタンを押すと言う話だとして 11回目は? 次の日とかは? ブラウザの戻るを押した場合は? 質問に、ここら辺の説明が無いと 既に出した1~10の乱数を覚えるバッファをstatic にすればいいのか セッションにすればいいのか、postでやり取りするのか 全然やり方が変わると思うのですがどうなのでしょうか

aabbccddzz
質問者

補足

ご回答、補足要求ありがとうございます。説明不足な点がおおくあり大変失礼いたしました。あなた様の補足要求を拝見し、確かにおっしゃるとおりと思いましたので、一応?の部分の補足説明をさせていただきます。もしこれで、何か方法がございましたらご回答宜しくお願い致します。 >10人がアクセスしたら、10人に違う数値を出せと言うことですか? ■はい、そうです。今は何人アクセスしようが、同じ数字を出さないようにしたいのです。 >同じ人(ブラウザ)が、10回、数を出すボタンを押すと言う話だとして >11回目は? ■そうですね、1から10と書かせていただきましたが、1から11あるいは1から100になる可能性も考え、数は増えてもアクセスしたら同じ数字を出さないようにしたいです。 >次の日とかは? ■たとえば、Aさんが8回ボタンをおしましたが、次の日9回からのカウントになるわけではありません。 数を出すときに、カウントしていて、初期値0を与えていますので、また1からとなります。 >ブラウザの戻るを押した場合は? ■戻るボタンをおしたら、またカウントの初期化なり、0からカウントされます。そしてまた、ランダムで同じ数字をださないように、の繰り返しです。 ■■私はサーブレットで、ランダムを出し、モデルに数を入れ、JSPに参照させております。MVCでこの流れをしております。なぜMVCなのかは、話が複雑になりますので、今は何でもよいですので、方法やその記述の仕方等、教えてくださる方がおりましたら、お願いしたいと思っております。以上補足説明をさせていただきました。

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.2

整数値の順序数をArrayListなどに入れて、Collections.shuffle()メソッドでシャッフルします。それをArrayListの先頭から順に使います。

aabbccddzz
質問者

お礼

専門家はやはりさまざまことご存知ですね。 そのような方法があるとは。 あの、お手数ですが、先ほどのアドバイスを付け加えるとしたら、 私のプログラムをどのように記述したらよいか、例を打っていただけませんでしょうか? これは無理な頼みですので、だめな場合はご回答はなさらなくて大丈夫です。

  • DIooggooID
  • ベストアンサー率27% (1730/6405)
回答No.1

ここで得られた "乱数" の利用目的が分かりませんが、【同じ数を出さない】といった操作を加えた時点で、それは乱数ではなくなってしまいます。 例えば、{1,2,3,4,5,6,7,8,9,10} の集合から、任意に1つの要素を取り出す、と言うようなことを考えなければならないと思います。

aabbccddzz
質問者

お礼

確かに、おっしゃるとおりかもしれません。 同じ数字を出さない時点で、乱数ではないな、と思っておりました。 あなた様がアドバイスしてくださった考え方でも試したいと思います。 今後結果がでましたら、補足のところに載せていただくかもしれません。アドバイスありがとうございました。 今後もよろしくお願いいたします。

関連するQ&A

  • C#の乱数取得について

    C#の乱数取得について カテ違いですが、C#のカテゴリがないのでここで質問させていただきます。 C#の乱数取得について調べましたところ以下のプログラムサンプルを見つけました。 1| int seed = Environment.TickCount; 2| string s = ""; 3| 4| for (int i = 0; i < 10; i++){ 5| Random r = new Random(seed++); 6| for (int j = 0; j < 5; j++){ 7| s += r.Next(50).ToString("00") + " "; 8| } 9| s += Environment.NewLine; 10| } 11| this.textBox1.Text = s; C#は勉強し始めたばかりで、まだまだ知識不足なのでこのプログラムが理解できません。 今の自分の知識で考えたことは、 1行目、int型のseedに、C#の乱数を生成するときにデフォルトで設定されるseed値を格納。 2行目、stringクラスのsを定義。 5行目、Random型(?)rにseedを設定 7行目、わかりません。。乱数を取得してることはわかるのですが。 9行目、sに保持。 11行目、GUIに表示。 どなたか、詳しく解説していただけると助かります。 よろしくおねがいします。

  • 変数を取得したい

    例えば、次のようなプログラムで1個の乱数を取得します。その取得した乱数の一番下の桁の数字(0~9)だけに着目し、変数iなどに値を取得するといったことは出来ますでしょうか? import java.util.*; public class RandomTest { public static void main(String[] args) { Random generator = new Random(); for(int i=0; i<1; i++){ int ran = generator.nextInt(); System.out.println(ran); } } }

    • ベストアンサー
    • Java
  • 乱数を発生させて、それを配列して小さい順に並べる

    乱数の発生のさせ方は、質問集で見て import java.util.Random; class ransuu { public static void main(String args[]) { Random rand = new Random(); for ( int i = 0; i <10; i++){ int x = rand.nextInt(9); System.out.println(x); } } } を用いて表示できたのですが、そのあとの配列がよく分かりませんのでぜひ教えてください。ちなみに私の持っているテキストには任意の数(22、80、57、60、50など)を並べ替えるというものはあるのですが、今回のような乱数+配列の例が載っていないのでよく分かりませんでした。

    • ベストアンサー
    • Java
  • 一様乱数?疑似乱数?

    0.0以上~1.0未満の範囲のdouble型一様乱数rdmを1000個発生させて、ヒストグラムをつくりたいのですが、このような書き方で良いのか、ご教示願えませんでしょうか。 ヒストグラムと言っても、グラフではなく、区間0≤u<0.1、0.1≤u<0.2、…、0.9≤u<1.0の10区間とし、配列aaに格納しているだけです。 また、「Math.random」を用いるやり方は理解できるのですが、下記のような書き方はいまいち納得できません。 疑問点1つ目、前者は毎回発生する乱数が違うのに、後者は同じですよね?なぜでしょうか。後者は毎回決まった値が出るので、初期値(seed)から決まった計算をしているということでしょうか。 疑問点2つ目、//kokoの次の行に x = rdm.nextDouble(); のように発生させた乱数を一時的に入れておかなくてもよいのでしょうか。 import java.util.*; public class test { public static void main(String [] args) { int aa [] = new int [10]; long seed = 999L; Random rdm = new Random(); rdm.setSeed(seed); for(int i = 0; i < 1000; i++){ for(int j=1; j<=10; j++){//koko if(rdm.nextDouble() < ((j-1)*0.1) && rdm.nextDouble() >= (j*0.1)) aa[j-1] = aa[j-1] + 1; } } for(int i=0; i<10; i++){ System.out.println( aa[i] ); } } }

    • ベストアンサー
    • Java
  • javaのプログラム

    int型の配列の各要素に1~10の乱数を代入し、各要素の値を縦向きの*のグラフで表示するプログラムを作っているのですが、結果がランダムででるので、自分の書いたプログラムが正しいのかわかりません。ソースを載せますので合っているのか間違っているか教えて下さい。もし間違っているならどこが間違いなのか教えていただけると嬉しいです。よろしくお願いします。 ●ソース import java.util.Random; import java.util.Scanner; class Graph { public static void main(String[] args){ Random rand = new Random(); Scanner stdIn = new Scanner(System.in); System.out.print("要素数:"); int n = stdIn.nextInt(); int a[] = new int[n]; for (int i = 0; i < n; i++) a[i] = 1 + rand.nextInt(10); for (int i = 1; i <= 10; i++){ for (int j = 0; j < n; j++) if (a[j] <= i) System.out.print("* "); else System.out.print(" "); System.out.println(); } } } ●実行例 要素数:12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

    • ベストアンサー
    • Java
  • JAVAで配列を使って * を縦向きのグラフで表示したいです。

    JAVAの勉強をしています。 このプログラムは配列に乱数を生成して * を 横向きにするプログラムです。 練習問題で、以下のプログラムを書き換えて、* を縦向きのグラフで表示する問題なのですが、解く方法がわかりません。 どなたか答えもしくはヒントを下さい。 よろしくお願いします。 import java.util.Random; import java.util.Scanner; public class Test06_04 { public static void main (String[] args) { Random rand = new Random(); Scanner stdIn = new Scanner(System.in); System.out.print("要素数 : "); int n = stdIn.nextInt(); //要素数を読み込む int[] a = new int[n]; //配列を生成 for (int i = 0; i < n; i++) { a[i] = 1+ rand.nextInt(10); } for (int i = 0; i < n; i++) { System.out.print("a[" + i + "] : "); for (int j = 0; j < a[i]; j++) System.out.print('*'); System.out.println(); } } }

    • ベストアンサー
    • Java
  • javaの配列部分ででエラーがでます。

    javaの配列部分ででエラーがでます。 マインスイーパを作っており爆弾の位置を決めるところでエラーの原因がわからず困っています。 9×9で、 ランダムでかぶらないように10個の爆弾を置くプログラムを作りたいです。 Random rnd=new Random(); int[][] mine=new int[8][8]; for(int i=0;i<=9;i++){ int yoko=(rnd.nextInt()>>>1)%9; int tate=(rnd.nextInt()>>>1)%9; if(mine[yoko][tate]!=10)mine[yoko][tate]=10; //爆弾があるところは10 else i--; } よろしくお願いします。

    • ベストアンサー
    • Java
  • 乱数について

    MathクラスのRandomメソッドを使用して、hairetu[i] = (int)(Math.random() * 100);のように乱数を取得しているのですが、このMath.randomについても、平均を取ると大体、真ん中の50になる等の特徴があるかもしれません。一様乱数と標準正規乱数が関係するのでしょうか?この2つの違いについて教えてください(^^;

    • ベストアンサー
    • Java
  • 要素数が10の配列で、乱数0~9の値が重複しないようにする方法がわからなくて困っています。

    JAVAの練習問題でわからなくて困っています 以下は線形探索のプログラムで、このプログラムを改良して、 要素数が10の配列で、乱数0~9の値が重複しないようにする方法がわからなくて困っています。 以下のような簡単なプログラムでできる方法で行いたいです。 どなたか答えまたはヒントを下さい、お願いします。 ------------------------------------------------------------ import java.util.Random; import java.util.Scanner; public static void main (String[] args) { Random rand = new Random(); Scanner stdIn = new Scanner(System.in); final int n = 10; //要素数 int[] a = new int[n]; //配列を宣言 for (int j = 0; j < n;) a[j] = rand.nextInt(10); System.out.print("配列aの全要素の値\n{ "); for (int j = 0; j < n; j++) System.out.print(a[j] + " "); System.out.println("}"); System.out.print("探す数値 : "); int key = stdIn.nextInt(); int i; for (i = 0; i < n; i++) if (a[i] == key) break; if (i < n) //探索成功 System.out.println("それはa[" + i + "]にあります。"); else //探索失敗 System.out.println("それはありません。"); } }

  • 乱数の作成について(初心者)

    Java初心者です。 -9から2の乱数を作成したのですが、乱数の出る確立が揃えられなくて困ってます。 どなたかお願いします。 import java.util.Random; class Rando2{ public static void main(String[] args){ Random x=new Random(); //-9から2の中から選びたい int n=x.nextInt(10); int f=x.nextInt(2);//0ならマイナスをつける if(2<n) n=-n;//-9から-3の作成(1/10の確立) else//-2から2の作成(1/20の確立) if(f==0) n=-n; System.out.print("あなたの好きな整数は"+n+"ですね?"); } }

    • ベストアンサー
    • Java

専門家に質問してみよう