第4講 If文の学習

第9話 順位(ランク)付けと並び替えの考え方(ヒント)

本当は、この話を解答例の話題にするつもりでした。
ところが、考えてみると予想以上の難問で、
初心者の方が理解できるプログラミングにするにはどうしたらよいか、
思い悩んでしまいました。
後に学ぶ配列を使うと、割に簡単にできるのですが、
まだ配列を学んでいませんので、配列は使えません。
思案を重ねた結果、実質配列と同じであるDataGridViewを使用することにしましたが、
それでもかなり初心者の方には、難しいのです。

2話後、3話後の第11話と第12話は、
この講座の中でもっとも難しい部分であることを宣言しておきたいと思います。
丁寧に説明していきますが、
それでもついてくるには、結構忍耐力と粘りが必要です。
がんばりどころですので、是非根性でついて来ていただければと強く祈念します。
世界で一番わかりやすいVisual Basic講座と銘打っていますが、
プログラミングを理解するには、不屈の粘りは必要です。
プログラムは何万行何十万行の中のたった一つのスペリングミスで、思うように動きません。
本当は小文字で書くべきところをうっかり大文字にしたために、
つまりちょっとしたケアレスミスのために、ビルドエラーしたり、動作がエラーしたりします。
しかも、その原因究明がすんなりいくときもありますが、1週間も1ヶ月も難航することもあります。
特に動作不良(例えば、200題に1題ぐらいの割合で別解のある数独(ナンバープレイス)を作ってしまうとか)の場合、
根本的な考え方のミスなのか、ケアレスミスなのかなかなかわからないものです。
実際、数独問題作成ソフトの開発において200題に1題の割合で別解のある問題作ってしまうという問題に遭遇したとき、
1週間以上原因が解明できませんでした。
プログラムの根幹に関わる致命的な欠陥である可能性を考え、
永久に解明できないのではないかと悲観していましたが、
原因は結局たった一つの綴りミスでした。
プログラムを趣味か仕事にするには、不撓不屈の忍耐力と粘りが必要です。

さて、本題に戻りましょう。
以下述べる方法は私が考えた方法です。
私の考えは、未熟でもっと簡単な方法があるかもしれません。
初心者の方もご一緒に考えていただければと思います。
そして、私が考えた方法よりもっとわかりやすい方法を思いつかれた方は是非メールしてください。
このサイト上で、HNないしは本名で紹介させていただきます。
(2017/10/01に児玉清一郎さんから、素晴らしいアイデアを頂きました。
私のランク付けは以下に述べますように、
最初は同点者を考慮に入れずに、
順位付けをして、次に同点者の順位が異なっている場合、
同点者の中で一番順位が高い順位にすべてそろえてから、
順位順に並び替えて、
上から順番に、1,2,3,・・・,i,・・・,40と打ち込み、
最後に再び出席番号に並び替えるという稚拙な方法で50行を超えるコーティングが必要なものでしたが、
児玉さんの方法は私のように迂路を経ずに、
直接ランク付けするのもので、行数はたったの10行程度です。
プログラミングには、知識・技術よりアイデアが重要であることを見事に見せる見本です。
コードの紹介と解説を第14話で行いますので、
是非ご覧になってください。)


基本的な考え方は、最低点者の探索を繰り返すことです。
前話において、各教科の最高点と最低点を導くプログラムを考えました。
当然合計点の40人中の最低点を導くことも簡単です。
実は、これを探し出したときにすでに成績最下位者は確定していることになります。
同点者がいた場合はとりあえず、出席番号最下位者を40位とします。
次に、この人を除いた39人について、最低点者を見いだし、
同点者がいた場合同様に出席番号最下位者を39位とします。
以下、38人、37人、36人、・・・、2人について同じことを繰り返せば、
同点なのに別順位がついてしまうという可能性を残していますが、
一応の順位付けが完了したことになります。

同点なのに別順位がつく可能性があるという問題は、後で解消します。

以上の考え方を聞いても、初心者の方は手も足も出ないというところではないでしょうか。
課題は、まだまだ山積しています。

40人の中からとえあえずの最下位者を確定したとき、
この1人をどう対象から外すかです。
私の考えた方法を示します。
成績最下位者の行と出席番号40番の人の行を交換します。
こうすれば成績下位者は41行目(1行目は、出席番号や国語などの列見出しでした。41行目はdataGridView1(*,40])に対応します。
dataGridView1(*,0)が1行目だからです。)にくることになります。
この41行目を探索対象から除外するのです。

次に、39人の中から最低点者を見いだし、それを40行目と交換し40行目を探索対象から外します。
以下同様に、39行目、38行目、37行目、
        ・
        ・
        ・
と除外を繰り返していけば、結局41行目から2行目まで探索対象から外されます。
つまり、除外される行数だけに注目して書き直すと、
41,40,39,38,・・・
そうです。
これならfor文の対象にできます。
For i = 40 To 1 Step -1
  For j = 1 To i
      ・
      ・
      ・
  Next
Next

今回の注目部分はFor j = 1 To iです。こういう使い方を覚えると、For文の使える範囲が一気に広がります。

さて、その行ごとの交換をするにはどうしたらよいでしょうか。
交換プログラムを次の話の課題としたいと思います。


並び替えができても、新たな課題が発生します。すべての問題が解決するのは、第13話ということになります。




第8話へ 第10話へ

006

VC++講義第1部へ
vb講義へ
VB講義基礎へ

数学研究室に戻る