最終講 卒業研究と卒業試験

第2話 課題1 順列を2次元に並べる

課題1は前に作った順列作成ソフトを少し改良すれば出来ます。
9次順列を2次元に並べるだけです。

セルの内容 
セル番号 


0 1 2
3 4 5
6 7 8

下のコーティングのgはセル番号に対応しています。
順列のときと同じでセルのラベル(すなわちセル番号)であるとセルに入っている数字(セルの内容)を区別しないと訳がわからなくなります。



ビール瓶で例えれば、『一番搾り』がラベルで、内容が『ビール』でしたね。
セル番号(セルのラベル)と内容(1から9までの行列を構成する数字)を明確に区別して下さい。
上図の右側のiはfor(i=0;i<9;i++)のiに対応し、gはSub f(ByVal g As Integer)のgです。
このgは0から8へと進んでいきます。

0 1 2
3 4 5
6 7 8

次のコーティング例は、この課題だけとしては少し難しいかもしれませんが、
最終的には数独(ナンバープレイス)解答作成が目的ですから、
それとの関連を考えてのことです。

コーティング例
Public Class Form1
   '変数の宣言と初期化
   Dim a(3, 3) As Integer, x(9) As Integer, y(9) As Integer, s As Integer
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     s = 0
     DataGridView1.Rows.Clear()
     h()
     f(0)

     DataGridView1.Rows.Add() '1行追加
     '見出し表示
     DataGridView1(6, 4 * s).Value() = "順"
     DataGridView1(7, 4 * s).Value() = "列"
     DataGridView1(8, 4 * s).Value() = "方"
     DataGridView1(9, 4 * s).Value() = "陣"
     DataGridView1(10, 4 * s).Value() = "総"
     DataGridView1(11, 4 * s).Value() = "数"
     '総数表示
     DataGridView1(12, 4 * s).Value() = s

   End Sub

   Sub h()
     For i = 0 To 8
       x(i) = i Mod 3
       y(i) = Int(i / 3)
     Next
   End Sub

   Sub f(ByVal g As Integer)
     If s = 100 Then Exit Sub  '計算時間が膨大なので100個で止めている。
     Dim h As Integer

     For i = 0 To 8
       a(y(g), x(g)) = i + 1
       h = 1
       If g > 0 Then
         For j = 0 To g - 1
           If a(y(j), x(j)) = a(y(g), x(g)) Then
             h = 0
             Exit For
           End If
         Next
       End If
       If h = 1 Then
         If g + 1 < 9 Then
           f(g + 1)
         Else
           For j = 0 To 2
             DataGridView1.Rows.Add() '1行追加
             For k = 0 To 2
               DataGridView1(k, j + 4 * s).Value = a(j, k)
             Next
           Next
           DataGridView1.Rows.Add() '1行追加
           s = s + 1 '総数カウント
           If s = 100 Then Exit Sub  '計算時間が膨大なので100個で止めている。
         End If
       End If
     Next

   End Sub

End Class

実行例

解説
   Sub h()
     For i = 0 To 8
       x(i) = i Mod 3
       y(i) = Int(i / 3)
     Next
   End Sub
では座標を計算しています。1次元のデータを2次元に対応させるためのものです。
x(0)=0,x(1)=1,x(2)=2
x(3)=0,x(4)=1,x{5)=2
x(6)=0,x(7)=1,x{8)=2
y(0)=0,y(1)=0,y(2)=0
y(3)=1,y(4)=1,y(5)=1
y(6)=2,y(7)=2,y(8)=3
と対応します。これを使えば1次元データを2次元に配置することが出来るのです。
尚、色対応でお分かりかと思いますが、ここでのiは、Sub f(ByVal g As Integer)のgに対応します。
gはセル番号=セルのラベルです。

今回のプログラミンで眼目部分は、Sub f(ByVal g As Integer)です。
これが自己再帰型で使われています。
If s = 100 Then Exit Sub を入れた理由は、すべて計算させるには時間がかかりすぎますので、
100個目で止めるためです。

       If h = 1 Then
         If g + 1 < 9 Then
           f(g + 1)
         Else
           For j = 0 To 2
             DataGridView1.Rows.Add() '1行追加
             For k = 0 To 2
               DataGridView1(k, j + 4 * s).Value = a(j, k)
             Next
           Next
           DataGridView1.Rows.Add() '1行追加
           s = s + 1 '総数カウント
           If s = 100 Then Exit Sub  '計算時間が膨大なので100個で止めている。
         End If
       End If
では、例えば、g=5のときは

1 2 3
4 5 1
* * *


と他が比べられます。同じものがあるときは、
h=0とすることによって強制的に






       If h = 1 Then
         If g + 1 < 9 Then
           f(g + 1)
         Else
           For j = 0 To 2
             DataGridView1.Rows.Add() '1行追加
             For k = 0 To 2
               DataGridView1(k, j + 4 * s).Value = a(j, k)
             Next
           Next
           DataGridView1.Rows.Add() '1行追加
           s = s + 1 '総数カウント
           If s = 100 Then Exit Sub  '計算時間が膨大なので100個で止めている。
         End If
       End If
をスルーさせています。そして、ループが進み

1 2 3
4 5 6
* * *





と問題をクリアさせています。




         If g + 1 < 9 Then
           f(g + 1)
の部分はg+1までしか進められません。

0 1 2
3 4 5
6 7 8


セル番号は右図をご覧なればお分かりのようにまでしかないからです。



大事な点を繰り返します。
順列のときと同じでセルのラベル(すなわちセル番号)であるとセルに入っている数字(セルの内容)を明確に区別して下さい。



上図の右側のiはFor i = 0 To 8のiに対応し、gはSub f(ByVal g As Integer)のgです。

0 1 2
3 4 5
6 7 8



セル番号は8でしかありませんので、
g+1が9のときは、



         Else
           For j = 0 To 2
             DataGridView1.Rows.Add() '1行追加
             For k = 0 To 2
               DataGridView1(k, j + 4 * s).Value = a(j, k)
             Next
           Next
           DataGridView1.Rows.Add() '1行追加
           s = s + 1 '総数カウント
           If s = 100 Then Exit Sub  '計算時間が膨大なので100個で止めている。
         End If
が実行されて、出来た方陣がDataGridViewに表示されます。



ここで課題です。現在

と使われない部分が多いので
実行結果が
となるように変更するにはどうしたらよいでしょうか。





第1話へ 第3話へ

006

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

数学研究室に戻る