こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

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に表示。


どなたか、詳しく解説していただけると助かります。

よろしくおねがいします。

投稿日時 - 2010-04-20 00:17:26

QNo.5838158

困ってます

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

> 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

投稿日時 - 2010-04-27 22:56:45

お礼

お礼が遅くなりましたが、丁寧な解説のおかげで無事解決することができました!

ホームページも一読させていただきました。
これからオブジェクト指向の考え方を、どんどん勉強していきたいと思います。

この度は、とてもわかりやすい説明をどうもありがとうございました。

投稿日時 - 2010-05-07 14:10:36

このQ&Aは役に立ちましたか?

14人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.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行目のメソッドの連続適用が複雑ですね。
 オブジェクト指向プログラム言語では、オブジェクト名.メソッド( )という表記方法がしょっちゅう出ます。様々なオブジェクトの様々なメソッドを調べながらプログラミングしていく訳です。

投稿日時 - 2010-04-20 02:03:39

補足

ご説明ありがとうございました。
大変わかりやすく、勉強になりました!

新たに疑問が生まれましたので、補足させていただきます。

5| Random r = new Random(seed++);
ですが、これは乱数を生成する度に必要でしょうか?

上のコードでは、4行目のfor文の関係でループする度にランダム型(?) r が生成(上書き?)されてますよね?

同じ乱数系列にしないために、ループごとにseedの値を1ずつプラスしなくちゃけないのはわかるのですが、こういった書き方でしか表現できないのでしょうか?

r.(Randomの中のにあるseedを格納した部分)++
このような考えが浮かんだのですが、間違っていると思われます。。。


また、ご回答いただけたらと思いますm(_ _)m

投稿日時 - 2010-04-21 00:25:54

あなたにオススメの質問