第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;
こちらでは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割ほど速くなります。
                         

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