第33講 数独(ナンバープレイス)問題解決ソフトVer.4の制作
(数独(ナンバープレイス)問題作成ソフトに挑戦する人は☆☆)


第3話 
Ver.7コード解説その1=全体構造解析関数の解説

ではこれから、5,6話にわたりコードの解説をしていきましょう。
全体構造解析も変わってしまいましたので、今回はこれを解説しましょう。
そして、次話では入力順構築、次次話では部分構造解析という順に解説していきます。

                         void zentaikouzoukaiseki(){
                                 register char i1,i2,i3,i4;

                                 char i1s,i2s;

                                 

                                 for(i1=0;i1<9;i1++){

                                         for(i2=0;i2<9;i2++){

                                                 if(a[i1][i2]==0){

                                                         for(i3=0;i3<9;i3++){

                                                                 lst[i1][i2][i3]=0;

                                                         }

                                                         for(i3=0;i3<9;i3++){

                                                                 if(a[i1][i3]>0)lst[i1][i2][a[i1][i3]-1]=1;

                                                         }

                                                         for(i3=0;i3<9;i3++){

                                                                 if(a[i3][i2]>0)lst[i1][i2][a[i3][i2]-1]=1;

                                                         }

                                                         i1s=i1/3;

                                                         i2s=i2/3;

                                                         for(i3=0;i3<3;i3++){

                                                                 for(i4=0;i4<3;i4++){

                                                                         if(3*i1s+i3!=i1 && 3*i2s+i4!=i2 && a[3*i1s+i3][3*i2s+i4]>0)lst[i1][i2][a[3*i1s+i3][3*i2s+i4]-1]=1;

                                                                 }

                                                         }

                                                         for(i3=0;i3<9;i3++){

                                                                 if(lst[i1][i2][i3]==0){

                                                                         rlst[i1][i2][b[i1][i2]]=i3+1;

                                                                         b[i1][i2]++;

                                                                 }

                                                         }

                                                         if(b[i1][i2]==1){

                                                                 iz[chs]=i1;

                                                                 jz[chs]=i2;

                                                                 chs++;

                                                         }

                                                 }

                                         }

                                 }

                         }
lst[i1][i2][i3]=0;を見ればお分かりのようにVer.3とはオンオフが逆になっています。
こちらでは0とき、オンすなわち入力可です。
0をオン、1をオフと定義しても、
その逆で定義してもそこはプログラマの自由です。

オンオフが反対なので
if(a[i1][i3]>0)lst[i1][i2][a[i1][i3]-1]=1;      
if(a[i3][i2]>0)lst[i1][i2][a[i3][i2]-1]=1;
if(3*i1s+i3!=i1 && 3*i2s+i4!=i2 && a[3*i1s+i3][3*i2s+i4]>0)lst[i1][i2][a[3*i1s+i3][3*i2s+i4]-1]=1;
if(lst[i1][i2][i3]==0){
はすべて逆になっています。
さて、新しく導入されたのが
                                                        if(b[i1][i2]==1){
                                                                 iz[chs]=i1;
                                                                 jz[chs]=i2;
                                                                 chs++;
                                                         }
の部分です。リスト候補数が1のときは、ここで番号(入力順)を決めてしまっています。
リスト候補数の最小値は、1であるからです。
このため

                         void nyuuryokujyunkoutiku(char g){

                                 register char i,j;

                                 register char Min,imin,jmin;                                 
                                 chsh[g]=0;

                                 if(g>=chs){
                                       
 Min=9;

                                         for(i=0;i<9;i++){

                                                for(j=0;j<9;j++){

                                                        if(a[i][j]==0){

                                                                if(b[i][j]<Min){

                                                                        Min=b[i][j];

                                                                        imin=i;

                                                                        jmin=j;

                                                                }

                                                        }

                                                        if(Min==2)break;

                                                }

                                                if(Min==2)break;

                                         }

                                         iz[g]=imin;

                                         jz[g]=jmin;

                                         chs=chs+1;

                                         chsh[g]=1;

                                 }

                         }

における無断な探索を省くことに成功しています。
ひとつ説明を落としていました。
register char i,j;
はレジスト変数と言われるものです。
レジスト変数は、CPU内のレジスタといわれる超高速のメモリーを使うことが出来ます。
普通は、CPUの外にあるメモリーを使っていますが、
C言語では、
レジスタを使うことが出来るのです。
レジスタは超高速のメモリーですから、
処理速度も2,3割ほど速くなります。

                         

     




第2話へ 第4話へ


戻る

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