1.課題
  Report#4:JavaアプリケーションとC言語のオリジナル問題作成と解答例{〜11/22(Mon)}
  制御文と配列を用いてオリジナルのJavaアプリケーションによる初級問題
(なるべく短い行数で)を作成し、模範解答例を示せ。併せて、同様な動作を行う
C言語のソースコードを示せ。
			
2.プログラム

/*
   Program     : sho3.java
   Student_ID  : 045754A
   Author      : Hayato MIYAGI
   Date        : 041122(Mon)
   Comments    : 初級問題
*/

import java.util.*;         //クラスライブラリーをインポート

public class sho3{      //sho3.java
   
    public static void main(String args[]){

        if(args.length != 1){             
            System.out.println("usage : java sho (The number of trial)");    //実行の仕方の例
            System.exit(1); // 異常終了
        }
        long seed = System.currentTimeMillis();   //時間で乱数値を決定
        
        Random random=new Random(seed);     //乱数ジェネレータを作成する
        int A = Integer.parseInt(args[0]);   //入力された命令回数をint型に変換
        int[] nums=new int[3];         //出力させる数字の個数を3個に指定
        int k;
        for(k = 0; k < A;k++){        //以下のfor文をA回繰り返す
            for(int i=0; i<nums.length; i++){       //
                nums[i]=random.nextInt(10);      //格納された数字をランダムに決定
                System.out.print(nums[i]);

            }

            System.out.println("");       //改行させるだけ
            int B = (100*nums[0])+(10*nums[1])+nums[2];   //Bは3桁の数字を作り出す配列の値を代入
            if(B == 777) {
                System.out.println("FEVER!!");       //"FEVER"と出力して改行
                k++;                             //kの値を1増やす
                break;                           //ループ文を抜ける
            }
        }
          
        System.out.println("trial : "+ k);         //実行した回数を出力
        if(k == A)                                 
            System.out.println("trial over!!");    /*指定した回数実行後に"777"がでなければ
                                                     "trial over"と出力される*/
          
           
    }
}

----------------------------------------------------------------------

----------------------------------------------------------------------

/*
   Program     : sho2.java
   Student_ID  : 045754A
   Author      : Hayato MIYAGI
   Date        : 041122(Mon)
   Comments    : 初級問題をC言語で作成
*/


#include &stdio.h>                    //printf()メソッドを使用するために<stdio.h>をインクルード
#include &stdlib.h>                   //random()メソッドを使用するために<stdlib.h>をインクルード
#include <time.h>                     //time()メソッドを使用するために<time.h>をインクルード


int main(int argc,char **argv){       // argcには引数の数,argvには引数の文字列が入る

  if(argc != 2){         //第2引数に何も入力されなかった場合

    printf("usage: ./sho2 (The Number of trial)\n");   //実行の仕方の例

    return 0;         //0の値を返して終了
  }

  long int A = atoi(argv[1]);   //第一引数をint型に変換間的に変化させる

  int B[3];        //配列Bの大きさを宣言

  int i,j,k;       //int型変数i,j,kを宣言


  for(i=0;i&A;++i)        //if文の使用
    {
      for(j=0;j&sizeof(B)/sizeof(int);++j)     //jの値を3に変換
        {
          B[j]=rand()%10;              //出力される数字を0〜9にランダムに決定
          printf("%d",B[j]);           //決定された数字を出力
        }

      printf("\n");      //改行を入れる
      k=(100*B[0])+(10*B[1])+B[2];   //3桁の数字を決定

      if(k==777){            //"777"が出力された場合
        printf("FEVER!! \n");    //"FEVER!!"を出力
        i++;          //iの値を1増加させる
        break;        //if文を抜ける
      }
      
    }

  printf("trial : %d\n",i);    //"trial : (iの値を出力)"
          if(i == A){       //"777"が発生しなかった場合
            printf("trial over!! \n");     //"trial over!!"を出力
          }      
}



3.実行結果

Javaで作成した初級問題の実行結果

[nw0454:~/prog2/repo4/3] j04054% java sho3 10
053
859
616
282
400
184
871
244
559
733
trial : 10
trial over!!

---------------------------------------------------------------

C言語で同様の動作をするプログラムの実行結果

[nw0454:~/prog2/repo4/2] j04054% ./sho2 10
388
057
973
095
468
513
427
559
331
223
trial : 10
trial over!! 

4.考察

初級問題としてまず、以下のように乱数を使ったプログラムを作成しました。

/*
Program : sho.java
Student_ID : 045754A
Author : Hayato MIYAGI
Date : 041122(Mon)
Comments : 初級問題1
*/ import java.util.*; public class sho{ //sho.java public static void main(String args[]){ long seed = System.currentTimeMillis(); //時間で乱数値を決定 Random random=new Random(seed); //乱数ジェネレータを作成する int[] nums=new int[3]; //出力させる数字の個数を3個に指定 for(int k = 0; k > 100;k++){ //以下のfor文を100回繰り返す for(int i=0; i>nums.length; i++){ nums[i]=random.nextInt(10); /*格納された10未満の数字をランダムに決定*/ System.out.print(random.nextInt(10)); //決定された数字を出力 } System.out.println(""); //改行させるだけ } } } -------------------------------------------------------------------------Result [miyagihayatonokonpyuta:~/prog2/repo4/1] j04054% java sho 044 771 219 964 508 304 433 895 984 360 519 735 124 680 078 788 728 916 991 860 . . . . . [miyagihayatonokonpyuta:~/prog2/repo4/1] j04054% java sho 481 902 843 765 926 195 956 118 606 181 804 112 . . .. .. ... [miyagihayatonokonpyuta:~/prog2/repo4/1] j04054% java sho 156 225 527 879 161 528 682 420 461 183 027 . . . . .. . .. [miyagihayatonokonpyuta:~/prog2/repo4/1] j04054% java sho 202 523 622 278 701 403 622 314 225 035 . . . . というふうに出力されます。 一回の実行で100個の出力がなされるまで続きますので残りは省かせてもらいます。 初めの考察として、for文の中身をみると、 for文ではランダムに出力された数字を3桁区切りにして出力し、その3桁の数字の 並びを100個出力するというものです。
ここで乱数の説明です。 乱数とは、規則性がなく,どのような数がでるかは確率的にしか予想できない 数をいう.しかし,コンピュータ等では乱数を発生させられるような技術はない. そこでコンピュータでは完全ではない擬似的な乱数を発生させるしくみをとっている.
random()メソッドを使用してわかったことはramdom()だけでは一定の並びの乱数しか
発生させることができないということです。
そこで、random()の引数にSystem.currentTimeMillis()という時間関数を与えてやる
と、時間の経過につられて発生する乱数が変化するということがわかりました。上記
の結果を見ればわかります。

次はさらにsho.javaプログラムを改良してもっと見やすくしていきます。
以下のように変更や追加をしました。

/*
   Program     : sho3.java
   Student_ID  : 045754A
   Author      : Hayato MIYAGI
   Date        : 041122(Mon)
   Comments    : 初級問題の補足
*/

import java.util.*;

public class sho3{      //sho3.java
   
    public static void main(String args[]){

        if(args.length != 1){             
            System.out.println("usage : java sho (The number of trial)");    //実行の仕方の例
            System.exit(1); // 異常終了
        }
        long seed = System.currentTimeMillis();   //時間で乱数値を決定
        
        Random random=new Random(seed);     //乱数ジェネレータを作成する
        int A = Integer.parseInt(args[0]);    //入力された命令回数をint型に変換
        int[] nums=new int[3];         //出力させる数字の個数を3個に指定
        int k;
        for(k = 0; k < A;k++){        //以下のfor文をA回繰り返す
            for(int i=0; i<nums.length; i++){       
                nums[i]=random.nextInt(10);      //数字をランダムに決定して格納
                System.out.print(nums[i]);       //決定、格納された数字を出力

            }

            System.out.println("");       //改行させるだけ
            int B = (100*nums[0])+(10*nums[1])+nums[2];   //Bは3桁の数字を作り出す配列の値を代入
            if(B == 777) {
                System.out.println("FEVER!!");       //"FEVER"と出力して改行
                k++;                             //kの値を1増やす
                break;                           //ループ文を抜ける
            }
        }
          
        System.out.println("trial : "+ k);         //実行した回数を出力
        if(k == A)                                 
            System.out.println("trial over!!");    /*指定した回数実行後に"777"がでなければ
                                                     "trial over"と出力される*/
          
           
    }
}

------------------------------------------------------------------------Result

[nw0454:~/prog2/repo4/3] j04054% java sho3 100
345
214
364
824
604
493
186
721
867
.
.
.
074
644
809
527
528
108
090
015
trial : 100
trial over!!


[nw0454:~/prog2/repo4/3] j04054% java sho3 100
018
756
484
681
112
349
727
401
562
.
.
.
.
182
484
705
507
834
883
022
trial : 100
trial over!!

[nw0454:~/prog2/repo4/3] j04054% java sho3 100
443
617
076
248
387
916
119
778
.
.
.
720
345
805
374
364
064
trial : 100
trial over!!


[nw0454:~/prog2/repo4/3] j04054% java sho3 100
130
275
510
426
932
786
777
FEVER!!
trial : 7

というふうに出力されます。

ここからsho3.javaプログラムの考察をしていきます。
まずは新しく追加した部分の説明からします。以下の部分に注目してください。

import java.util.*;

public class sho3{      //sho3.java
   
    public static void main(String args[]){

        if(args.length != 1){             
            System.out.println("usage : java sho (The number of trial)");    
            System.exit(1); 
        }
								.
								.
								.
								.
args[]とはコマンドラインからわたされる引数です。この配列args[]を上記のように
if文を用いて表すと、実行コマンドを実行するときに命令を何回実行するのかを自分で
決定することができます。以上のような処理ができれば、命令を1000回でも10000回で
も実行することができます。以下に実行の仕方の例をあげておきます。
実行例

[nw0454:~/prog2/repo4/3] j04054% java sho3 100
			                    ^
					命令させる回数を代入するのを忘れずに!
										
次は
public class sho3{      //sho3.java
   
    public static void main(String args[]){

        if(args.length != 1){             
            System.out.println("usage : java sho (The number of trial)");  
            System.exit(1); 
        }
        long seed = System.currentTimeMillis();   
        
        Random random=new Random(seed);    
        int A = Integer.parseInt(args[0]);    //入力された命令回数をint型に変換
						.
						.
						.
Integer.parseInt()とは型を変換するためのメソッドです。使う数字をint型で統一するため
に使用しました。
次のif文をみてください
							.
							.
							.
            if(B == 777) {
                System.out.println("FEVER!!");       //"FEVER"と出力して改行
                k++;                             //kの値を1増やす
                break;                           //ループ文を抜ける
            }

							.
							.
 上記のif文は配列nums[i]より出力されたint型変数Bのが"777"になったときの制御を
行っています。ここで問題が起こりました。
初め、k++;という一文が不足していたために"777"が出力されたときの実行回数とその
後出力される"trial : (実際に実行した回数)"が1ずれていました。
 つまり、"trial : (実際に実行した回数)"のほうが1不足していました。
そこで、"trial : (実際に実行した回数)"が出力される前にKの値を1増加させておけば
いいのではないかと思い、k++;をbreak;する前に追加しました。
すると、以下のようにうまく出力させることができました。

[nw0454:~/prog2/repo4/2] j04054% cat -n temp
     1  129
     2  211
     3  931
     4  705
     5  901
     6  161
     7  920
     8  860
     9  491
    10  145
    11  626
    12  850
    13  150
    14  512
    15  639
    16  480
    17  657
    18  127
    19  083
    20  034
    21  897
    22  928
    23  519
    24  926
    25  193
    26  874
    27  520
    28  204
    29  277
    30  294
    31  054
    32  522
    33  434
    34  729
    35  374
    36  640
    37  806
    38  469
    39  136
    40  614
    41  588
    42  570
    43  033
    44  161
    45  188
    46  862
    47  521
    48  777
    49  FEVER!! 
    50  trial : 48

次は実際に命令を実行した回数を超えてしまったときの処理をもう一度
if文を使って行いました。
					.
					.
					.
					
 System.out.println("trial : "+ k);         //実行した回数を出力
        if(k == A)                                 
            System.out.println("trial over!!");    /*指定した回数実行後に"777"がでなければ
                                                     "trial over"と出力される*/
					.
					.
					.
					
実行結果を見れば上記のif文が正しく動いていることがわかります。

以上でsho3.javaプログラムの考察を終わります。

以下に上記のJavaプログラムと同様の動作を行うプログラムをC言語
で作成してみました。

/*
   Program     : sho2.java
   Student_ID  : 045754A
   Author      : Hayato MIYAGI
   Date        : 041122(Mon)
   Comments    : 初級問題をC言語で作成
*/


#include &stdio.h>                    //printf()メソッドを使用するために&stdio.h>をインクルード
#include <stdlib.h>                   //random()メソッドを使用するために<stdlib.h>をインクルード
#include <time.h>                     //time()メソッドを使用するために<time.h>をインクルード


int main(int argc,char **argv){       // argcには引数の数,argvには引数の文字列が入る

  if(argc != 2){         //第2引数に何も入力されなかった場合

    printf("usage: ./sho2 (The Number of trial)\n");   //実行の仕方の例

    return 0;         //0の値を返して終了
  }

  long int A = atoi(argv[1]);   //第一引数をint型に変換

  srand((unsigned int)time(NULL));     //乱数値を時間的に変化させる

  int B[3];        //配列Bの大きさを宣言

  int i,j,k;       //int型変数i,j,kを宣言

  for(i=0;i&A;++i)        //if文の使用
    {
      for(j=0;j&sizeof(B)/sizeof(int);++j)     //jの値を3に変換
        {
          B[j]=rand()%10;              //出力される数字を0〜9にランダムに決定
          printf("%d",B[j]);           //決定された数字を出力
        }

      printf("\n");      //改行を入れる
      k=(100*B[0])+(10*B[1])+B[2];   //3桁の数字を決定

      if(k==777){            //"777"が出力された場合
        printf("FEVER!! \n");    //"FEVER!!"を出力
        i++;          //iの値を1増加させる
        break;        //if文を抜ける
      }
      
    }

  printf("trial : %d\n",i);    //"trial : (iの値を出力)"
          if(i == A){       //"777"が発生しなかった場合
            printf("trial over!! \n");     //"trial over!!"を出力
          }      
}

上記のsho2.cプログラムの考察をしていきます。
まずは以下の部分についてこうさつしていきます。

#include &stdio.h>                    //printf()メソッドを使用するために&stdio.h>をインクルード
#include <stdlib.h>                   //random()メソッドを使用するために<stdlib.h>をインクルード
#include <time.h>                     //time()メソッドを使用するために<time.h>をインクルード

 C言語ではヘッダファイルをインクルードすることにより
各ヘッダファイルに定義されている標準関数を使用する
ことができます。この作業は初めに行わないといけません。
 Java言語との違いはC言語は初めにインクルードという作業を
行いますがJava言語ではインポートという作業を行います。
このときインポートするものはJavaではクラスライブラリと
呼ばれるものです。Javaではこのクラスライブラリというものの
中に様々な標準クラスやメソッドが定義されています。

次は

long int A = atoi(argv[1]);   //第一引数をint型に変換

この一文はatoi();の引数をint型に変換するための一文です。

srand((unsigned int)time(NULL));     //乱数値を時間的に変化させる

C言語で乱数を発生させるためにはsrand();を使用します。

for(i=0;i&A;++i)        //if文の使用
    {
      for(j=0;j&sizeof(B)/sizeof(int);++j)     //jの値を3に変換
        {
          B[j]=rand()%10;              //出力される数字を0〜9にランダムに決定
          printf("%d",B[j]);           //決定された数字を出力
        }

 ここでsizeof(B)/sizeof(int)の動作の説明をします。
配列Bは大きさが3と宣言されていますがint型なので
実際は12バイトになっています。このため、上記の操作
を行わないと実際に実行してみたときに以下のように
おかしな結果が得られます。

[nw0454:~/prog2/repo4/2] j04054% ./sho2 5
7568183120022
4493193693843984140096
1601419163958898238401940744166901
trial : 8

となってしまい、コマンドラインで指定した命令実行回数と
実際に実行した回数(trial)の数が合っていません。
sizeof(B)/sizeof(int)の処理を行うことによって配列Bの大きさ
を3に指定することができます。

 ここであまり触れなかった部分についての説明をします。
Java言語とC言語。この両者には似通った表現がたくさん存在します。
 例えば、標準出力を行うものでは、

      Java--------System.out.print();
      C   --------printf();

のように似たもの同士が結構います。
よって、個人的に似たもの同士の説明は省かせていただきました。
							
以上で考察を終わります。

5.反省と感想
 今回のレポートは作成に時間がかかってしまいました。初級問題を
作成しようといろいろな問題(かけ算九九など)を考えましたが、やはり
少し面白いものを作成しようと思い、今回のスロットプログラムを
作成しました。問題はどうすれば乱数をうまく発生させることができる
のかと試行錯誤を重ねました。プログラムが完成したときはうれしかった
です。
 最後にこのスロットプログラムを何回も実行して気がついたのですが、
横一列に777を出力させるためには平均的に約800〜1000回くらい実行
しなければなりません。これより予想できることはカジノに行ってFEVER
するためには、一ゲームあたり50円としてFEVERを出すためには4〜5万円
も浪費してしまうという結果が得られます。さらに縦、横、斜めに777が
揃えるためには最低でも800*800*800=???00000,回実行というとんでも
ない数字が出てきてしまいます!こんなスロットを回すお金があるなら
もっと他のことにお金を使ったほうがイイと思いました。私にはギャンブル
にはまる人たちの気持ちがわかりません。怖いです。																


6.参考文献
  独習Java第2版               ジョセフ.オニール 著
                       トップスタジオ  訳
                       武藤 健志   監修
  C実践プログラミング	          Steve Oualline    著
                                     望月 康司      監修
				      谷口 功     約
 
戻るべし!