C#の乱数取得とは?

このQ&Aのポイント
  • C#で乱数を取得する方法について説明します。
  • 質問文のコードは、C#で乱数を生成して表示するプログラムです。
  • このプログラムでは、Environment.TickCountをシード値として乱数を生成し、5行目でその乱数を取得しています。
回答を見る
  • ベストアンサー

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に表示。 どなたか、詳しく解説していただけると助かります。 よろしくおねがいします。

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

  • ベストアンサー
  • seastar3
  • ベストアンサー率69% (99/142)
回答No.2

> 5| Random r = new Random(seed++); > ですが、これは乱数を生成する度に必要でしょうか? > 5| Random r = new Random(seed++); > 上のコードでは、4行目のfor文の関係でループする度にランダム型(?) r が生成(上書き?)されてますよね? > 同じ乱数系列にしないために、ループごとにseedの値を1ずつプラスしなくちゃけないのはわかるのですが、こういった書き方でしか表現できないのでしょうか?  逐次働きはお分かりのようで、追加質問はC#の乱数の扱い方の定番だと理解すればよろしいでしょう。  プログラムサンプルの5行目の Random r = new Random(seed++); のようにオブジェクトに名前をつけて使えるようにすることをインスタンス化といいます。そしてその実体化したオブジェクトをインスタンスと呼びます。プログラムサンプルでは、rというインスタンス名の乱数オブジェクトを設定する訳です。  このインスタンス化は、例えばコンピュータのメモリー上にある動作をする処理マシーンを設置するようなもので、あまりにたくさん設定したり古いインスタンスが溜まってしまうとメモリー不足になって通常のプログラムの動作に支障が出てしまう心配がおきます。したがって、インスタンスは使い終わったらそのメモリーを自由に使える状態に解放します。このサンプル内のインスタンス r なら、r = null; といったインスタンス解放のコマンドを8行目の下で働かせてもいいのです。  ところが、5行目で常に乱数オブジェクトrを作り直していますから、わざわざ null を使わなくてもかまわない訳です。そして、ある範囲のメモリー上に10回、乱数インスタンス r を繰り返し設置しているのです。7行目のような簡潔な記述で2桁の乱数を文字列オブジェクトsに並べています。  逆にインスタンスを10個作って、最後に文字列オブジェクトに流し込んでいっても間違いではない訳で、10個のインスタンスの解放を忘れないようにすればいいのです。  ちなみにオブジェクト指向に関して、私なりの説明をまとめたものが参考URLのコンテンツなので、よかったら読んでみて下さい。  

参考URL:
http://homepage1.nifty.com/tetsuhito/OOP-Labo/oop-menu.html
magister
質問者

お礼

お礼が遅くなりましたが、丁寧な解説のおかげで無事解決することができました! ホームページも一読させていただきました。 これからオブジェクト指向の考え方を、どんどん勉強していきたいと思います。 この度は、とてもわかりやすい説明をどうもありがとうございました。

その他の回答 (1)

  • seastar3
  • ベストアンサー率69% (99/142)
回答No.1

サンプルコードを逐次説明してみますと、 1| int seed = Environment.TickCount;   コンピュータの時計から乱数の種となる値を取り出し、整数型変数のseedに代入する。このseedを元に乱数が一定の出現パターンになるのを防ぐ。 2| string s = "";   結果の文字列(0以上50未満の整数2桁の乱数を5個並べた文字列が10行分埋め込まれることになる)を代入するための文字列 s を定義し初期化している。。 3| 4| for (int i = 0; i < 10; i++){   10行目までを、整数変数 i をカウンタとして用いて0回目から9回目まで10回繰り返させる。文字列を改行しながら、文字列変数 s に代入するための繰り返し。 5| Random r = new Random(seed++);   乱数オブジェクト r を作り出す。この際に1行目で設定した整数変数 seed を増やしながら乱数に種を与えていて、10回分の乱数が同じパターンになるのを防いでいる。 6| for (int j = 0; j < 5; j++){   8行目までを、整数変数 j をカウンタとして用いて0回目から4回目まで5回繰り返させる。5個の乱数を空白で区切って並べた文字列を文字列変数 s に代入するための繰り返し。 7| s += r.Next(50).ToString("00") + " ";   乱数オブジェクト r に0以上50未満の任意の整数を選び出させる。そして、その2桁の整数に文字列化メソッドToString()を働かせて、整数2桁で固定した文字列(例.3が選ばれても03と2桁で表現する)にしてしまう。さらにその文字列の後ろに半角の空白1文字を付け加えて見やすい文字列にしている。結局、15文字分の文字列が作られる。 8| }   6行目からこの8行目までをカウンタ jが5より大きくなるまで繰り返す。 9| s += Environment.NewLine;   文字列変数 s に改行記号を付け加える。つまり6行目から8行目までの繰り返しを抜けた後で文字列 s 内の文字列を折り返す。 10| }   4行目からこの10行目までをカウンタ iが10より大きくなるまで繰り返す。 11| this.textBox1.Text = s;   結果を埋め込み済みの文字列変数 s を自作フォーム上の文字表示部品 textBox1 に代入し、表示する。  以上のようになります。  7行目のメソッドの連続適用が複雑ですね。  オブジェクト指向プログラム言語では、オブジェクト名.メソッド( )という表記方法がしょっちゅう出ます。様々なオブジェクトの様々なメソッドを調べながらプログラミングしていく訳です。

magister
質問者

補足

ご説明ありがとうございました。 大変わかりやすく、勉強になりました! 新たに疑問が生まれましたので、補足させていただきます。 5| Random r = new Random(seed++); ですが、これは乱数を生成する度に必要でしょうか? 上のコードでは、4行目のfor文の関係でループする度にランダム型(?) r が生成(上書き?)されてますよね? 同じ乱数系列にしないために、ループごとにseedの値を1ずつプラスしなくちゃけないのはわかるのですが、こういった書き方でしか表現できないのでしょうか? r.(Randomの中のにあるseedを格納した部分)++ このような考えが浮かんだのですが、間違っていると思われます。。。 また、ご回答いただけたらと思いますm(_ _)m

関連するQ&A

  • 一様乱数?疑似乱数?

    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
  • 文字列から乱数を作る方法について。

    最近PHPの勉強をしており、文字列をhash関数の入力として用いて、0~100の乱数を生成する機能を実装しました。 ですが、出力結果に偏りがみられます。 再現性を残して、できるだけ偏りの無い乱数を作りたいと考えています。 何かいいアイデアやサイトを御存知でしたら教えてください。 現在は以下のようなコードで乱数を生成しています。 $seed = hash("sha512",$setstring); $seed = $seed[0].$seed[1].$seed[2]; $seed = intval($seed,10); srand($seed); for($i=0; $i<10; $i++){ $lv = rand()%100; }

  • 乱数を使って

    プログラム #include<stdio.h> #include<string.h> #include<stdlib.h> main() { char land[10][10]; int i, j; for(i=0; i<10; i++) { for(j=0; j<10; j++) { strcpy( &land[i][j], "□"); printf("%s",&land[i][j]); } printf("\n"); } } で発生させた10×10の□の上に、 乱数を使って■を25個上書きしたいのですが、 どうしたらできるか教えてください。

  • 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
  • 変数を取得したい

    例えば、次のようなプログラムで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
  • 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
  • 乱数の取得

    キー操作をした時に複数の乱数を習得させようと思っています。 【キ─操作関数】  int num[3] = {11, 22, 33}; ←初期化のため数字は適当です。  srand((unsigned int)time(NULL))  for(int i=0; i<=3; i++)  {   num[i] = rand % 10;  } 上記のプログラムを書いています。 num[0]、num[1]、num[2]にそれぞれ0~9の乱数が入ると思うのですが、 num[0]にしか乱数が入りません。 num[1]、num[2]には同じ数字(恐らくtimeで取得した数字?)が入っています。 何かお気づきの点がありましたらアドバイスお願い致します。

  • コンパイルできません。

    コマンドプロンプト上で、乱数をいくつか取得するというプログラムを作成したいのですが、コンパイル出来なくて困っています。発生させる乱数を0~900までの数字の中から0~9個のうちのいずれかの個数だけ取得するようにしたいです。j< の所に変数を記述するのはダメなのでしょうか?わかる方いましたらお願いします。 import java.util.*; public class RandomTest{ int rand; public static void main(String[] args){    Random generator = new Random();    for(int i=0; i<1; i++){     int rand = (int)(Math.random() * 10);    }    for(int j=0; j<rand; j++){     int ran = (int)(Math.random() * 1000);       System.out.println(ran);    } } }

    • ベストアンサー
    • Java
  • 一度に複数の値を取得できる乱数ってありますか?

    PHP Version 5.1.6を使っています。 例えば、1から10まで整数の中から値が重複しないように ランダムに8個選びたいような時で、自分が思いつた選び方は、 for($i=0; $i<8; $i++){ $r = rand(1, 10); $flag = false; for($j=0; $j<Count($list); $j++){ if($r == $list[$j]){ $flag = true; break; } } if($flag){ $i--; continue; } $list[] = $r; } print_r($list); なんですが、これだと効率が悪いような気がします・・・ そこで重複しないようにランダムに選べる乱数や またはそういう関数はあるのでしょうか?

    • 締切済み
    • PHP
  • 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

専門家に質問してみよう