其中ResovleCells()函數的參數含義是: 輸入數獨遊戲的原始狀態.
如下就是data.txt一個範例:
0 0 0 8 0 2 1 0 0
0 0 0 0 0 0 6 0 5
0 0 4 6 1 5 0 0 0
6 9 0 0 0 0 0 3 0
4 0 0 1 6 8 0 0 9
0 7 0 0 0 0 0 4 6
0 0 0 7 8 1 5 0 0
7 0 2 0 0 0 0 0 0
0 0 8 2 0 9 0 0 0
可以運行本程式求解得到:
5 3 6 8 7 2 1 9 4
2 1 7 9 3 4 6 8 5
9 8 4 6 1 5 3 2 7
6 9 5 4 2 7 8 3 1
4 2 3 1 6 8 7 5 9
8 7 1 5 9 3 2 4 6
3 4 9 7 8 1 5 6 2
7 5 2 3 4 6 9 1 8
1 6 8 2 5 9 4 7 3
Successful
//================================================// main.cpp#include "ShuDu.h"int main(){ CShuDu shudu; shudu.ResolveCells("data.txt"); return 0;} //===============================================// ShuDu.h#ifndef __SHUDU_H__#define __SHUDU_H__#include <memory.h>#include <iostream>#include <string>#include <fstream>using namespace std;typedef int ELEMTYPE;typedef int BOOL;#define FALSE 0#define TRUE 1class CShuDu{public: CShuDu(); BOOL ResolveCells(const string &filename); ~CShuDu();private: BOOL InitCells(const string &filename); BOOL RecursionBody(int position); BOOL CheckValid(int row, int col); BOOL PrintCells();protected: ELEMTYPE m_iCells[9][9]; BOOL m_bReadOnly[9][9];};// ============================================================CShuDu::CShuDu(){ // Initial primative cells to 0. memset(m_iCells, 9*9, sizeof(ELEMTYPE));}CShuDu::~CShuDu(){ // nothing to do}BOOL CShuDu::InitCells(const string &filename){ ifstream infile; ELEMTYPE iCount; infile.open(filename.data()); if(!infile) { // open file fail cout<<filename<<" open fail!"<<endl; return FALSE; } iCount = 0; while(!infile.eof() && iCount < 81) { // read data to m_iCells array ELEMTYPE *pCurrentInput = &m_iCells[iCount/9][iCount%9]; BOOL *pCurrentBool = &m_bReadOnly[iCount/9][iCount%9]; infile>>*pCurrentInput; if(*pCurrentInput < 0 || *pCurrentInput > 9) { cout<<"Init data "<<*pCurrentInput<<" out of range!"<<endl; return FALSE; } else { if(*pCurrentInput != 0) *pCurrentBool = TRUE; else *pCurrentBool = FALSE; ++iCount; } } if(iCount != 81) { // total number error cout<<"Total input data number error!"<<endl; return FALSE; } return TRUE;}BOOL CShuDu::PrintCells(){ int i, j; for(i=0; i<9; ++i) { for(j=0; j<9; ++j) cout<<" "<<m_iCells[i][j]; cout<<endl; } return TRUE;}BOOL CShuDu::CheckValid(int row, int col){ int i, j; ELEMTYPE *pCurrent = &m_iCells[row][col]; // check row for(j=0; j<9; ++j) { if(m_iCells[row][j] == *pCurrent) { if(j != col) return FALSE; } } // check col for(i=0; i<9; ++i) { if(m_iCells[i][col] == *pCurrent) { if(i != row) return FALSE; } } // check sub 9-cells int m = row / 3; int n = col / 3; for(i=m*3; i<(m+1)*3; ++i) { for(j=n*3; j<(n+1)*3; ++j) { if(m_iCells[i][j] == *pCurrent) { if(pCurrent != &m_iCells[i][j]) return FALSE; } } } // no the same element yet, it is valid at present status. return TRUE;}BOOL CShuDu::ResolveCells(const string &filename){ if(!InitCells(filename)) return FALSE; BOOL bResult = RecursionBody(0); if(bResult) cout<<"Successful"<<endl; else cout<<"Failure"<<endl; return bResult;}BOOL CShuDu::RecursionBody(int position){ if(position >= 81) { // get the right answer PrintCells(); return TRUE; } int row, col; row = position / 9; col = position % 9; while(position < 81 && m_bReadOnly[row][col]) { ++position; row = position / 9; col = position % 9; } if(position >= 81) return RecursionBody(position); // still exist cells that have not be filled. ELEMTYPE *pCurrent = &m_iCells[row][col]; for(int i=1; i<=9; ++i) { *pCurrent = i; if(!CheckValid(row, col)) continue; // get the correct answer if(RecursionBody(position+1)) return TRUE; } *pCurrent = 0; return FALSE;}#endif