第5講 配列の学習

第5話 配列による成績一覧表の改良
第4話問題解答例
#pragma endregion
   private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
           int i,j,max,min,w;

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

           //1行目 列見出し
           dataGridView1[0,0]->Value =L"番号 ";
           dataGridView1[1,0]->Value =L"国語 ";
           dataGridView1[2,0]->Value =L"社会 ";
           dataGridView1[3,0]->Value =L"数学 ";
           dataGridView1[4,0]->Value =L"理科 ";
           dataGridView1[5,0]->Value =L"社会 ";
           dataGridView1[6,0]->Value =L"合計 ";
           dataGridView1[7,0]->Value =L"平均 ";
           dataGridView1[8,0]->Value =L"最高点 ";
           dataGridView1[9,0]->Value =L"最低点 ";
           dataGridView1[10,0]->Value =L"合否 ";
           dataGridView1[11,0]->Value =L"順位 ";
           dataGridView1[12,0]->Value =L"講評  ";

           //出席番号とランダムデータの発生
           for(i=1;i<=40;i++){
             dataGridView1[0,i]->Value =i+L" ";
             for(j=1;j<=5;j++){
               dataGridView1[j,i]->Value =rand()%101;
             }
           }

           //42行から45行 行見出し
           dataGridView1[0,41]->Value =L"合計 ";
           dataGridView1[0,42]->Value =L"平均 ";
           dataGridView1[0,43]->Value =L"最高点 ";
           dataGridView1[0,44]->Value =L"最低点 ";

           //ランダムデータの配列へのコピー
           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;
             }
           }

     }
};
}

どうです。結構難しいでしょう。dataGridView1[*,*]と列行が反対だったり、
dataGridView1[j,i]とa[i][j]のjが1つずれたりずれなかったりと、考えるのが大変です。
一気に直そうとせず、


           
//ランダムデータの配列へのコピー
           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++){
             //合計・平均の算出
             w=0;
             for(j=1;j<=5;j++){
               w=w+(int)(dataGridView1[j,i]->Value);
             }
                     ・

                     ・
                     ・

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

           
*/

のように
/**/で挟み、ここは無効にしておいて、ピンクを加えてビルドして成功することを確認したら、
           
//ランダムデータの配列へのコピー
           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"よく勉強して再挑戦!";
                    }
                  }
                }
              }
            }

        
            
/*
                ・
                ・
                ・
            
*/
/**/の挟みの範囲を
//行(横)合計・平均・合否・講評の算出と表示分だけ縮め、
ここでもビルドしてうまくいったら、さらに挟みの範囲を絞り、改良しまたビルドがうまくいったらさらに絞るということを繰り返して、
コーティングされてください。
このように少しずつやっていかないと、ビルドエラーや実行エラー(ビルドはうまくいったが、意図した通りの結果が出ない)など
の原因の究明が難しいものです。
例えば、
          //ランダムデータの配列へのコピー
           int a[40][7];
           for(i=0;i<40;i++){
             for(j=0;j<6;j++){
               a[j][i]=(int)(dataGridView1[j,i+1]->Value);
             }
           }


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

                     ・
                     ・

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

           */
としておいてビルドするとうまくいきません。
/**/で挟まれた部分は注釈部分でコンピュータをこの部分を全く無視して読みませんから、
原因は
           int a[40][7];
           for(i=0;i<40;i++){
             for(j=0;j<6;j++){
               a[j][i]=(int)(dataGridView1[j,i+1]->Value);
             }
           }

部分に特定されます。そして、このコーティング部分をよく読んで、a[j][i]
にミスがあることが発見されます。正しくは、a[i][j]ですね。

/**/
の利用以外にメモ帳利用するコーティングやバックアップ方法についても、
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ第5講配列の学習第5話配列による成績一覧表の改良
でも解説していますので、そちらも参照されてください。

さて、解説は次話で行いましょう。


第4話へ 第6話へ

025


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

数学研究室に戻る