javaの乱数生成プログラム-バグを教えてください

このQ&Aのポイント
  • Web上で「重複しない乱数」を作るプログラムをいくつか見まして、どれもこれも何でこんな複雑なステップを踏むのであろう思い、どーだこんなに簡単に作れるじゃん・・・
  • 生成する乱数の数が100個とか200個とかなら問題ないんですが、例えば9桁の乱数を10000個作るように設定しても7500個くらいしかListに入りません。
  • 原因がどこにあるかお教えいただけますでしょうか。なにとぞよろしくお願いします。
回答を見る
  • ベストアンサー

javaの乱数生成プログラム-バグを教えてください

こんにちは。Web上で「重複しない乱数」を作るプログラムをいくつか見まして、どれもこれも何でこんな複雑なステップを踏むのであろう思い、どーだこんなに簡単に作れるじゃん・・・と0-9までの整数で乱数を生成するプログラムを書いてみたんです。これならAPI調べなくたって基本を身につけていれば誰でも書けると・・・けど、生成する乱数の数が100個とか200個とかなら問題ないんですが、例えば9桁の乱数を10000個作るように設定しても7500個くらいしかListに入りません。原因がどこにあるかお教えいただけますでしょうか。なにとぞよろしくお願いします。 import java.util.ArrayList; import java.util.List; public class RandomExec { static int idLength=9; //乱数の桁数を指定 static int elmSize=100; //生成する乱数の個数を指定 static List<String> list = new ArrayList<String>(); //乱数を格納するリスト public static void main(String[] args) { addList(); //生成された乱数を要素に持つリスト list を取得 //要素をひとつずつコンソール出力 for(String s : list){ System.out.println(s); } } //リストに入れるための乱数を生成するメソッド public static String addId(){ int[] id=new int[idLength]; //int配列idを宣言(要素数=乱数の桁数) String s=""; String str; //配列にMath.random()で取得した要素を入れる for(int i=0; i<idLength; i++){ int n=(int)(Math.random()*10); id[i]=n; } //指定した桁数(この場合は9個)の数字から成るString s を得るため //int型配列idの要素をStringに変換し、すべての要素を連結する for(int n : id){ str = String.valueOf(n); s+=str; } return s; //生成されたStringを返す(下のaddList()メソッドに返しています) } //addIdメソッドで作った要素候補をチェックし、重複がなければListに加えるメソッド //List list の要素数が変数elmSizeで指定した乱数の数と同じになるまで繰り返す public static void addList(){ while(list.size()<elmSize){ //addIdメソッドでlistの要素候補strを取得 String str = addId(); //listに候補と同じ文字列を持つ要素が存在しなければlistに加える if(!list.contains(str)) list.add(str); } } }

  • Java
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • duron
  • ベストアンサー率77% (73/94)
回答No.1

eclipseで実行結果を確認しているのであればコンソールの出力バッファを 超えているために前のほうが消えているのではないでしょうか? 参考URL先を見て設定を変更してみてください。 もし他の方法で出力しているのであれば一行ずつ出力するループの前後に "start","end"を出力して結果にもそれが出力されるか確認してみてください。

参考URL:
http://www.hitachi.co.jp/Prod/comp/soft1/manual/pc/d3M4160/EM410047.HTM
ushioja
質問者

お礼

ご回答ありがとうございました。バッファが足りない・・・どうして思いつかなかったのでしょう。まだjavaのプログラミングに自信がなくて、期待通りに動かないと即バグだとおもってしまうんです。それにしても今回の質問は穴があったら速攻で入ります。

その他の回答 (1)

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.2

いろいろ突っ込みどころの多いコードだけど 動作上のバグはないわね。 その 7500個くらい というのはどうやって図ったの? たぶんその図り方に問題があると思っているわ。 mainを public static void main(String[] args) throws Exception { PrintStream out = new PrintStream(new File("C:\\log.log")); addList(); // 生成された乱数を要素に持つリスト list を取得 // 要素をひとつずつコンソール出力 for (String s : list) { out.println(s); } } こう書き換えて実行後log.logを見てみなさい。 ちゃんと10000個出ているはずよ。

ushioja
質問者

お礼

ご回答ありがとうございました。おっしゃるとおりです。もう、何も考えずあたふたとつまらない質問をしてしまいましてすみませんでした。質問する前にファイルに落として確認するとか、当然のことなのに。これから気をつけます。

関連するQ&A

  • Javaのプログラムで・・・

    Javaのプログラムで1~20までの整数乱数を実行後に指定回数だけ発生させ、そのうち何%が奇数であったかを表示するプログラムを作成中です。 乱数を発生させるところまでは行ったのですがここからどのように計算していくのかわかりません。 以下が作成したものですがアドバイスお願いします。 import java.io.*; public class Rand { public static void main(String args[]) throws IOException { System.out.print("発生させる乱数の回数は?"); BufferedReader br= new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine(); int num= Integer.parseInt(str); for(int i=1;i<=num;i++){ int a=(int)(20*Math.random()+1); System.out.println(a); } for(int a=1; a<=;a++){ if(a%2==1); System.out.println("発生した乱数の"++"%が奇数です。"); } } }

  • javaの配列

    javaの配列なんですが、配列の全要素一気にメソッドを実行させることができますか? 例えば、 Turtle[] hm = new Turtle[3]; for(int i = 0; i < 3; i++){ hm[i] = new Turtle(); } と配列を生成し、fd(int s)←[sピクセル前進]というメソッドを配列の全部の要素を順番ごとにではなく全部同時に実行させたい場合、コードはどのように書けばよいのでしょうか?

    • ベストアンサー
    • Java
  • Javaのプログラムが完成出来ません・・・

    この前、大学からこんな課題が出されました。 以下の条件が含まれてるシェルソートのプログラムを作成せよ。 条件。 ・ソート済み部分に新しい値を挿入するための空き場所を作るメソッドを入れること。 ・配列の逆順数を計算するメソッドを入れる。 ・今の歩幅より一段階小さい歩幅を計算するメソッドを入れる。 ・配列の大きさに一番合った歩幅を計算するメソッドを入れる。 ・歩幅hの挿入ソートを行うメソッドを入れる。 ・シェルソートを行うメソッドを入れる。 ・mainメソッドを完成させ、ソート過程を表示しながらシェルソートを実行するようにする。 ・作成したプログラムが正しく選択ソートを実行していることが分かる実行結果を示すこと。 ・値は、 a[0]=0, a[1]=30, a[2]=20,a[3]=10 一応プログラムは、 class ShellSort{ static int compare = 0; static int copy = 0; static void showArray(int a[], int N){ //2-0:逆順数と共に配列の内容を表示するメソッド //動作:N個の要素を持つ配列aの要素を全て画面に表示する //} static void initArray(int a[], int N){ //2-0:配列にランダムな値を代入するメソッド //動作:N個の要素を持つ配列aに対し、1~Nまでの範囲の数をランダムに入れる //ただし、a[0]には常に0を入れること。 } static int shiftLargerElements(int a[], int v, int i){ //2-0:ソート済み部分に新しい値を挿入するための空き場所を // 作るメソッド //動作:配列aに対し、a[i]より手前にあるvより大きい要素を後ろ //に1つずつずらしてvを挿入するための空き場所を作る。最後に、 //できた空き場所の添え字を戻り値として返す。 //空き場所を作るまでに行った比較回数を変数compareに加算 //空き場所を作るまでに行ったコピー回数を変数copyに加算      int space = 0; int j; j = i; while((compare++ >= 0) && (a[j-1] > v)){ a[j] = a[j-1]; copy++; j--; } space = j; return space; } static int shiftLargerElements(int a[], int v, int i, int h) { //2-1:ソート済み部分に新しい値を挿入するための空き場所を // 作るメソッド //動作:配列aに対し、a[i]より手前にある要素 //a[i-h],a[i-2h],a[i-3h],...のうち、vより大きい各要素を後ろに //hだけ移動させてvを挿入するための空き場所を作る。 //最後に、できた空き場所の添え字を戻り値として返す。 //空き場所を作るまでに行った比較回数を変数compareに加算 //空き場所を作るまでに行ったコピー回数を変数copyに加算 int space = 0; return space; } 現在はここまでしか作成出来てません。 それ以降でつまづいています。 分かる人がいましたら、是非教えて下さい。

  • javaの表示方法がわかりません。

    javaを勉強しているのですがもう少しと言うところで悩んでいます。 配列の中身を見て同じコードがある場合にはその個数をカウントし表示するというようなことをしたいのですが表示部分でうまくいきません。 初歩的な質問ですみませんが、どうやって重複しないで表示させることができるのでしょうか。 **表示させたい結果** 001は2個 003は2個 004は1個 005は4個 ********* **表示される結果** 001は2個 001は2個 003は2個 003は2個 004は1個 005は4個 005は4個 005は4個 005は4個 ********* **ソース** class str{ public static void main(String args[]){ int i = 0; int j = 0; int S = 0; String test[] ={"001","001","003","003","004","005","005","005","005"}; String str1 = ""; String str2 = ""; for(i=0;i<9;i++){ str1 = test[i]; for(j=0;j<9;j++){ str2 = test[j]; if(str1.equals(str2)){ S++; } } System.out.println(str1 + "は" + S + "個"); S = 0; } } } *********

  • 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のプログラムについての質問です。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。  注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中に番号を振ってあります。 import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.List; class LocalList implements List{  private int Count;  private String Data[];  private Iterator ite;  private ListIterator lite;  // コンストラクタ  void mylist(){   Data = new String[10];   Count = 0;  }  (1)  public boolean add(Object str){   if(Count >= 10){    return false;   }   Data[Count ++] = new String((String)str);   return true;  }  public void add(int i,Object str){  }        public boolean addAll(Collection c){   return false;  }        public boolean addAll(int i,Collection c){   return false;  }    (2)  public void clear(){   Count = 0;  }  public boolean contains(Object str){   return false;  }          public boolean containsAll(Collection c){   return false;  }  public boolean equals(Object str){   return false;  }    (3)  public Object get(int i){   return (i >= Count);  }  public int hashCode(){   return -1;  }  public int indexOf(Object str){   return -1;  }  public boolean isEmpty(){   return false;  }  public Iterator iterator(){   return ite;  }     public int lastIndexOf(Object str){   return -1;  }     public ListIterator listIterator(){   return lite;  }     public ListIterator listIterator(int i){   return lite;  }    (4)  public Object remove(int i){   return (i >= Count);  }    public boolean remove(Object str){   return true;  }         public boolean removeAll(Collection c){   return false;  }         public boolean retainAll(Collection c){   return false;  }    (5)  public Object set(int i,Object str){   return Data[i];  }    (6)  public int size(){   return Count;  }  public List subList(int i,int j){   return this;  }  public Object[] toArray(){   return Data;  }  public Object[] toArray(Object[] a){   return Data;  } } class Main {  public static void main(String[] args) {   mylist sub = new mylist();   sub.add("ビルドバーニングガンダム");   sub.add("ライトニングガンダム");   sub.add("ウイニングガンダム");   sub.add("ガンダムフェニーチェリナーシタ");   sub.add("R・ギャギャ");   for(int i = 0; i < sub.size(); i++){      System.out.println(sub.get(i));   }   // 改行   System.out.println();   // setメソッド   sub.set(1,"ガンダムエピオン");   for(int i = 0; i < sub.size(); i++){    System.out.println(sub.get(i));   }   // 改行   System.out.println();   // sizeメソッド   System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n");   // removeメソッド   sub.remove(1);   for(int i = 0; i < sub.size(); i++){       System.out.println(sub.get(i));   }   // clearメソッド   sub.clear();   System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです");    } } setメソッドとremoveメソッド以外は起動するのようになったのですが、この2つがうんともすんとも動きません。ジェネリクス型を使うという考え方もあるらしいのですが、ネットで調べてもピンと来ず寸詰まり状態になってしまっています。後少しだと思うのですが。。。。 どなたかご教授頂けないでしょうか?よろしくお願い致します。

  • java プログラム 範囲を指定した乱数

    正規乱数をボックスミューらー法で発生させて、 範囲を指定して出力したいと思ってます。 プログラムを作成してみたのですが・・・ 平均50で範囲を48から52にしたいのですが たまに範囲外というか「0.0」が出力されてしまいます。 アドバイスをください import java.util.*; public class test2{ public static void main(String args[]){ double R,S; double r[]=new double[200];  double s[]=new double[200]; double s1[]=new double[200]; Random ran=new Random();    for(int i=0;i<200;i++){     R=ran.nextDouble(); S=50+Math.sqrt(-2*Math.log(ran.nextDouble()))*Math.cos(2*Math.PI*(ran.nextDouble())); r[i]=R; s1[i]=S; if(50-2<s1[i]){ if(50+2>s1[i]){ s[i]=s1[i]; } } } for(int j=0;j<150;j++){ System.out.println(s[j]); } } } お願いします

    • ベストアンサー
    • Java
  • プログラムの合体。

    jump7799_4836さん 2018/7/2103:34:44 public class Test2 { public static int メソッド () { System.out.println("メソッド()が呼ばれました"); return 0; } public static int メソッド (int i) { System.out.println("メソッド(int i)が呼ばれました"); return i; } public static int メソッド (int i, int j) { System.out.println("メソッド(int i, int j)が呼ばれました"); return i; } public static int メソッド (short s) { System.out.println("メソッド(short s)が呼ばれました"); return s; } public static int メソッド (double d) { System.out.println("メソッド(double d)が呼ばれました"); return (int) d; } } public メソッド class Test2 { public メソッド static void main(String[] args) { Test2.メソッド (); Test2.メソッド (1); Test2.メソッド (1,2); Test2.メソッド (1.1); Test2.メソッド ((short) 1); Test2.メソッド ((double)1); } } kouzou@GD348ZZD9:/WORK$ javac Test2.java Test2.java:29: エラー: class、interfaceまたはenumがありません public メソッド class Test2 { ^ Test2.java:30: エラー: <identifier>がありません public メソッド static void main(String[] args) { ^ エラー2個 2つのプログラムが合体することってあるのですか? いつもすみません。 解説のほど、宜しくお願い申し上げます。

    • ベストアンサー
    • Java
  • javaプログラムについて

    クラスの出席番号順にString型配列nameに名前が、 * int型配列scoreにテストの点数が格納されています。 * * 出席番号1 大悟 74点 * 出席番号2 琴音 70点 * 出席番号3 勇輝 88点 *       ・ *       ・ *       ・ *       ・ *       ・ * * このクラスの最高得点者の名前と、最低得点者の名前を * 表示するメソッドを作成してください。 * */ public class MethodAdd8 { public static void main(String[] args){ String[] name = {"大悟", "琴音","勇輝","葵","綾乃","和樹","凛","愛花","結愛","孝太郎"}; int[] score = {74,70,88,82,96,64,80,61,72,79}; //メソッドの呼び出し score("綾乃",1); score("愛花",2); } //ここにメソッドを追加してください public static void score(String name,int score){ if(score==1){ System.out.println("綾乃"); }else{ System.out.println("愛花"); } } } この配列から、最高得点者と最低得点者は分かるので上記のようにしたところ、 score配列の中から最高得点者と最低得点者を探すように、と言われました。 考え方やヒントなどをお願いします。

  • java(バブルソート/単純挿入ソート)

    以下のプログラムを「バブルソートもしくは単純挿入ソートのプログラムに変更しなさい」という課題が出ました。 どのようにすればよろしいでしょうか? import java.util.*; public class SelectSort { //プログラムクラス名 //整列プログラム public static void main(String[] args){ //整列用 int 型配列 int[] target; int elems = KeyboardInput.askInt("要素数? "); //配列を乱数で初期化する target = setArray(elems); //初期状態を表示 display(target); //整列メソッドの呼び出し sortArray(target); //整列結果の表示 display(target); } //配列を乱数で初期化するメソッド static int[] setArray(int elems){ // 要素数個の int 型変数の確保 int[] array = new int[elems]; //乱数利用ための宣言 Random generator = new Random(); //乱数の最大値・最小値 int max = 100; int min = 0; //generator.nextDouble() で 0から1までのdouble型乱数発生 for(int i=0 ; i<array.length ; i++) { array[i] = (int)((max-min)*(generator.nextDouble())+min); } return array; } //配列の状態を表示 static void display(int[] array){ for(int i=0 ; i<array.length ; i++) { System.out.print(array[i]+" "); } System.out.println(""); } static void sortArray(int[] array){ //配列のはじめから最後まで繰り返す for( int i = 0; i < array.length-1 ; i++){ int min_id = i; int min = array[i]; //範囲中でもっとも小さい要素を探す for( int j=i+1 ; j< array.length ; j++ ) { if( array[j] < min ){ min = array[j]; min_id = j ; } } //範囲の始めと置き換える int tmp = array[i]; array[i] = array[min_id]; array[min_id] = tmp; //display(array); } } }

専門家に質問してみよう