第5講 配列の学習

第6話 配列による成績一覧表の改良の解説その1

           
//45行加える
           for(i=0;i<45;i++)dataGridView1->Rows->Add();

           //ランダムデータの配列へのコピー
           int a[40][7];
           for(i=0;i<40;i++){
             for(j=0;j<6;j++){
               a[i][j]=(int)(dataGridView1[j,i+1]->Value);
             }
           }

           //行(横)合計・平均・合否・講評の算出と表示
           for(i=1;i<=40;i++){
             //合計・平均の算出
             a[i-1][6]=0;
             for(j=1;j<=5;j++){
               a[i-1][6]=a[i-1][6]+a[i-1][j];
             }
             //合計・平均の表示
             dataGridView1[6,i]->Value=a[i-1][6];
             dataGridView1[7,i]->Value=((double)a[i-1][6])/5;

             //合否の表示
             if(a[i-1][6]>=250) dataGridView1[11,i]->Value=L"合格";
             if(a[i-1][6]<250) dataGridView1[11,i]->Value=L"不合格";

             //講評の表示
             if(a[i-1][6]>=350){
               dataGridView1[12,i]->Value=L"上位合格です。";
             }
             else{
               if(a[i-1][6]>=280){
                 dataGridView1[12,i]->Value=L"余裕で合格です。";
               }
               else{
                 if(a[i-1][6]>=250){
                    dataGridView1[12,i]->Value=L"ぎりぎり合格です。";
                 }
                 else{
                    if(a[i-1][6]>=230){
                       dataGridView1[12,i]->Value=L"合格まで後一歩。";
                    }
                    else{
                       dataGridView1[12,i]->Value=L"よく勉強して再挑戦!";
                    }
                  }
                }
              }
            }

            //教科合計・平均の算出と表示
            for(i=1;i<=6;i++){
              //合計・平均の算出
              w=0;
              for(j=1;j<=40;j++){
                w=w+a[j-1][i];
              }
              //合計・平均の表示
              dataGridView1[i,41]->Value=w;
              dataGridView1[i,42]->Value=w/40;
            }
 
            //各個人の最高点・最低点の算出と表示
            for(i=1;i<=40;i++){
              //各個人の最高点・最低点の算出
              max=0; min=100;
              for(j=1;j<=5;j++){
                if(a[i-1][j]>max)max=a[i-1][j];
                if(a[i-1][j]<min)min=a[i-1][j];
              }
              //各個人の最高点・最低点の表示
              dataGridView1[8,i]->Value=max;
              dataGridView1[9,i]->Value=min;
            }

            //各教科の最高点・最低点の算出と表示
            for(i=1;i<=5;i++){
              //各教科の最高点・最低点の算出
              max=0; min=500;
              for(j=1;j<=40;j++){
                if(a[j-1][i]>max)max=a[j-1][i];
                if(a[j-1][i]<min)min=a[j-1][i];
              }
              //各教科の最高点・最低点の表示
              dataGridView1[i,43]->Value=max;
              dataGridView1[i,44]->Value=min;
            }

            //成績順並び替え
            int bn;
            Object^ w1; //Object^型変数の用意
   
            for(i=40;i>=2;i--){
              min=500;
              for(j=1;j<=i;j++){
                if(a[j-1][6]<=min){
                  min=a[j-1][6];
                  bn=j;
                }
              }
              for(j=0;j<=6;j++){
                w2=a[bn-1][j];
                a[bn-1][j]=a[i-1][j];
                a[i-1][j]=w2;
              }
              for(j=0;j<=12;j++){
                w1=dataGridView1[j,bn]->Value;
                dataGridView1[j,bn]->Value=dataGridView1[j,i]->Value;
                dataGridView1[j,i]->Value=w1;
              }
            }
                
           for(i=1;i<=40;i++){
             dataGridView1[10,i]->Value=i;
           }
           for(i=2;i<=40;i++){
             if(a[i-2][6]==a[i-1][6])dataGridView1[10,i]->Value=dataGridView1[10,i-1]->Value;
           }

           //出席番号順並び替え
           for(i=40;i>=2;i--){
             max=0;
             for(j=1;j<=i;j++){
               if(a[j-1][0]>max){
                 max=a[j-1][0];
                 bn=j;
               }
             }
             for(j=0;j<=6;j++){
               w2=a[bn-1][j];
               a[bn-1][j]=a[i-1][j];
               a[i-1][j]=w2;
             }
             for(j=0;j<=12;j++){
               w1=dataGridView1[j,bn]->Value;
               dataGridView1[j,bn]->Value=dataGridView1[j,i]->Value;
               dataGridView1[j,i]->Value=w1;
             }
           }

  
さて、1行1行解説していきましょう。

最初の1行for(i=0;i<45;i++)dataGridView1->Rows->Add();
は45行を加えています。for(i=0;i<45;i++)dataGridView1->Rows->Add(); は
for(i=0;i<45;i++){
  dataGridView1->Rows->Add();
}
簡略表現です。{}中が1つの命令しかないときは、このようにも記述できます。
この辺はif文に似ています。
if(条件式){
  A;
}
は if(条件式)A;
とすることもできました。if文でも複数の命令があるときは、
if(条件式){
  A;
  B;
  ・
  ・
  ・
}
と記述しなければなりません。


まず、次の6行について見ていきましょう。
           //ランダムデータの配列へのコピー
           int a[40][7];
           for(i=0;i<40;i++){
             for(j=0;j<6;j++){
               a[i][j]=(int)(dataGridView1[j,i+1]->Value);
             }
           }

int a[40][7]; は40行7列の配列を用意します。
出席番号1番から40番までで40行分のデータがあります。
列の方は、出席番号・国語・社会・数学・理科・英語・合計の7列です。
a
合計値まで配列に入れるのは、後に合計値を使って並び替えをするからです。
VBから入ってきた方は、うっかりすると40行7列に対して、
int a[39][6]; とされてしまうかもしれません.。
VBでは、Dim a(39,6) As Integer と宣言すれば、40行7列の配列を用意したことになりました。
理由は、39や6は最後の添え字数を意味しているからです。
VBでは、Dim a(9) As Integer と宣言すれば、
a(0),a(1),a(2),a(3),a(4),a(5),a(7),a(8),a(9)
で10個の配列変数を用意したことになります。a(0)も個数に入るからです。
ですから、Dim a(39,6) As Integer なら
a(0,0),a(0,1),a(0,2),a(0,3),a(0,4),a(0,5),a(0,6),
a(1,0),a(1,1),a(1,2),a(1,3),a(1,4),a(1,5),a(1,6),
           ・
           ・  
           ・
           ・
a(39,0),a(39,1),a(39,2),a(39,3),a(39,4),a(39,5),a(39,6)           
で確かに40×7個の変数を用意しています。
ところが、VC++では、int a[9]; の9は最後の添え字の数を表すのではなく、配列変数個数を表しますので、
a[0],a[1],a[2],a[3],a[4],a[5],a[7],a[8]
が用意されたことになります。当然a[9]は用意されていませんので、a[9]=5; 等とするとエラーします。
ですから、
a[0][0],a[0][1],a[0][2],a[0][3],a[0][4],a[0][5],a[0][6],
a[1][0],a[1][1],a[1][2],a[1][3],a[1][4],a[1][5],a[1][6],
           ・
           ・  
           ・
           ・
a[39][0],a[39][1],a[39][2],a[39][3],a[39][4],a[39][5],a[39][6]     
を用意したければ、int a[39][6]; ではなくint a[
40][7]; としなければならないのです。

次に気をつけなければならないのは、
a[i][j]=(int)(dataGridView1[j,i+1]->Value);
の部分です。iとjが反対であり、iは1つずれています。
q
DataGridViewは、最初の行は0行目と数えます。
           //ランダムデータの配列へのコピー
           int a[40][7];
           for(i=0;i<40;i++){
             for(j=0;j<6;j++){
               a[i][j]=(int)(dataGridView1[j,i+1]->Value);
             }
           }
ですから、(int)(dataGridView1[列番号,行番号]->Value)の行番号と出席番号が一致しています。
列も最初は0列目と数えるので、
1列目2行目すなわち出席番号1の欄は、(int)(dataGridView1[0,1]->Value)ですし、
2列目2行目すなわち出席番号1番の国語の成績41の欄は、(int)(dataGridView1[1,1]->Value)です
1列目2行目すなわち出席番号1の欄は、一番最初のデータですからそれに対応する配列は当然a[0][0]ですし、
2列目2行目すなわち出席番号1番の国語の成績41の欄は、a[0][1]です。
(int)(dataGridView1[
0,1]->Value)とa[0][0]、(int)(dataGridView1[1,1]->Value)とa[0][1]
(列と行が反対ですから、対応も反対です。)
が1つずれ、ピンクは一致します。
これが、
a
[i][j]=(int)(dataGridView1[j,i+1]->Value);
となっている理由です。

           //行(横)合計・平均・合否・講評の算出と表示
           for(i=1;i<=40;i++){
             //合計・平均の算出
             a[i-1][6]=0;
             for(j=1;j<=5;j++){
               a[i-1][6]=a[i-1][6]+a[i-1][j];
             }
             //合計・平均の表示
             dataGridView1[6,i]->Value=a[i-1][6];
             dataGridView1[7,i]->Value=((double)a[i-1][6])/5;

             //合否の表示
             if(a[i-1][6]>=250) dataGridView1[11,i]->Value=L"合格";
             if(a[i-1][6]<250) dataGridView1[11,i]->Value=L"不合格";

             //講評の表示
             if(a[i-1][6]>=350){
               dataGridView1[12,i]->Value=L"上位合格です。";
             }
             else{
               if(a[i-1][6]>=280){
                 dataGridView1[12,i]->Value=L"余裕で合格です。";
               }
               else{
                 if(a[i-1][6]>=250){
                    dataGridView1[12,i]->Value=L"ぎりぎり合格です。";
                 }
                 else{
                    if(a[i-1][6]>=230){
                       dataGridView1[12,i]->Value=L"合格まで後一歩。";
                    }
                    else{
                       dataGridView1[12,i]->Value=L"よく勉強して再挑戦!";
                    }
                  }
                }
              }
            }


2番目を考究しましょう。
a[i-1][6]は改良前ではwでした。これは、7列目(列は0列目から始まるから)
i
の合計です。a[0][6]は上図の緑の枠の欄を表すます。
したがって、
             for(j=1;j<=5;j++){
               a[i-1][6]=a[i-1][6]+a[i-1][j];
             }

は、各行の合計を計算しています。
             //合計・平均の表示
             dataGridView1[6,i]->Value=a[i-1][6];
             dataGridView1[7,i]->Value=((double)a[i-1][6])/5;

             //合否の表示
             if(a[i-1][6]>=250) dataGridView1[11,i]->Value=L"合格";
             if(a[i-1][6]<250) dataGridView1[11,i]->Value=L"不合格";

             //講評の表示
             if(a[i-1][6]>=350){
               dataGridView1[12,i]->Value=L"上位合格です。";
             }
             else{
               if(a[i-1][6]>=280){
                 dataGridView1[12,i]->Value=L"余裕で合格です。";
               }
               else{
                 if(a[i-1][6]>=250){
                    dataGridView1[12,i]->Value=L"ぎりぎり合格です。";
                 }
                 else{
                    if(a[i-1][6]>=230){
                       dataGridView1[12,i]->Value=L"合格まで後一歩。";
                    }
                    else{
                       dataGridView1[12,i]->Value=L"よく勉強して再挑戦!";
                    }
                  }
                }
              }

各行は、a[i-1][6]を使った合計・平均・合否・講評の処理と表示です。

            //教科合計・平均の算出と表示
            for(i=1;i<=6;i++){
              //合計・平均の算出
              w=0;
              for(j=1;j<=40;j++){
                w=w+a[j-1][i];
              }
              //合計・平均の表示
              dataGridView1[i,41]->Value=w;
              dataGridView1[i,42]->Value=w/40;
            }

の部分は改良前と基本的に同じですが、合計の算出に配列a[行][列]を使用しています。
以後の解説は次話で。

第5話へ 第7話へ

025


vc++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ

数学研究室に戻る