您当前的位置:首页 > 互联网教程

用C语言如何随机生成一个数独

发布时间:2025-05-14 09:30:40    发布人:远客网络

用C语言如何随机生成一个数独

一、用C语言如何随机生成一个数独

数独生成算法?这个还真不好搞,不过我当初写数独游戏的时候随便捣鼓出来过一个,你自己去改改吧,至于这个算法能不能生成所有的数独,我还真没论证过。

原理:对一个给出的数独棋盘的所有行或列交换给出的两个数X、Y,数组仍满足数独规则。如给出1、2,则对所有列交换1、2的位置,数组仍满足数独规则。

由于对棋盘的演进是随机的,所以相当于随机生成数独棋盘啦。每次演进的次数最好大一点,10次以上吧,以保证每个数都被换过位置。

具体代码就不用我写了吧,嘎嘎……

二、用c语言写一个简易数独的思路。要代码

1、if((xy[x][y]==xy[i][y]&&i!=x)||(xy[x][y]==xy[x][i]&&i!=y))

2、for(i=0,m=x/3*3,n=y/3*3;i<9;i++)

3、if(xy[x][y]==xy[m+i/3][n+i%3]&&m+i/3!=x&&n+i%3!=y)

4、for(xy[x][y]=1;xy[x][y]<=9;xy[x][y]++)

5、}

输入为9行9列整数,已知的整数填写对应的数字,尚待计算的未知数字填写0。

6、输入为9行9列整数,已知的整数填写对应的数字,尚待计算的未知数字填写0。

7、该代码的思路很简单,就是从第一行第一列开始依次填入数字,检查是否是在同一行、同一列、同一宫有没有填入重复数字,如果没有就继续填入下一个数字,如果有就返回。

8、虽然效率稍低,但原理简单、表述直白、易于理解,更有效率的代码是使用十字链表完成,如有兴趣可继续深入

三、求数独源码

int tempNum[81];//上一次填数位置

int tempSp= 0;//上一次填数位置指标

int startB[81];//九宫格位置的起点

int addB[9];//九宫格位置的加值

int main(int argc, char*argv[]){

if(argc>1) for(j=0; j<81; j++) sudoku[j]= argv[1][j]-'0';

//参数设定(设定这些参数之后,无论检查行、列、九宫格都方便多了)

startH[i]= i/9* 9;//列位置的起点

startV[i]= i% 9;//行位置的起点

startB[i]=((i/9)/3)*27+((i%9)/3)*3;//九宫格位置的起点

addB[i]=(i/3)*9+(i%3);//九宫格位置的加值

int sp=getNextBlank(-1);//取得第一个空白的位置开始填入数字

sudoku[sp]++;//将本位置数字加 1

if(sudoku[sp]>9){//如果本位置的数字已大於 9时则回到上一个位置继续测试

if(check(sp)==0){//如果同行、列、九宫格都没有相同的数字,则到下一个空白处继续

push(sp);//当然,如果发现有相同的数字时,就需把原位置的数字加 1(所以本处什麼都不做)

} while(sp<81&& sudoku[sp]>0);

//检查同行、列、九宫格有没有相同的数字,若有传回 1

if(!fg) fg= check1(sp, startH[sp], addH);//检查同列有没有相同的数字

if(!fg) fg= check1(sp, startV[sp], addV);//检查同行有没有相同的数字

if(!fg) fg= check1(sp, startB[sp], addB);//检查同九宫格有没有相同的数字

int check1(int sp, int start, int*addnum){

//检查指定的行、列、九宫格有没有相同的数字,若有传回 1

if(sp!=sp1&& sudoku[sp]==sudoku[sp1]) fg++;

else return(tempNum[--tempSp]);

参考资料:算法如下,先构造一个9*9的结构体数组,表示棋盘数据0表示空白未知,结构体中每个元素

包含一个1-9的数组作为备选数字.

构建好一个棋盘之后依次对每个空白位置进行备选数字中进行删除.当前已经填写的数字就全部删除

如果只剩下一个备选数字就将该备选数字填写到棋盘数据中.该算法在AI这个函数中实现.

当无法用AI算法推出结果的时候就进行回朔法,见找到有两个备选数字的元素,选取其中一个,

继续往下填写,直到全部填写上去(结束),或者无法继续填写(某个空白位置没有备选元素).

如果无法继续填写下去就表示最初选择的那个数据是错误的,直接填写另外一个数据到棋盘上.

如此下去就能够填写出棋盘中的所有元素.

unsigned int Data[SIZE]={//未解棋盘数据

const int temp[9]={ 1, 2, 3, 4, 5, 6, 7, 8, 9};

Item():data(0),other(temp,temp+9){}

inline Item& operator=(const Item& src)

inline Item& operator=(int x){

std::copy(temp,temp+sizeof(temp)/sizeof(temp[0]), other.begin());

inline operator int(){return data;}

const int Group1,Group2,Group3;

GroupInfo(int g1,int g2,int g3):Group1(g1),Group2(g2),Group3(g3){}

inline bool operator==(GroupInfo& src){

return((Group1|Group2|Group3)&(src.Group1|src.Group2|src.Group3))?true:false;

GroupInfo( 1<<1, 1<<10, 1<<19),GroupInfo( 1<<1, 1<<11, 1<<19),GroupInfo( 1<<1, 1<<12, 1<<19),GroupInfo( 1<<1, 1<<13, 1<<20),GroupInfo( 1<<1, 1<<14, 1<<20),GroupInfo( 1<<1, 1<<15, 1<<20),GroupInfo( 1<<1, 1<<16, 1<<21),GroupInfo( 1<<1, 1<<17, 1<<21),GroupInfo( 1<<1, 1<<18, 1<<21),

GroupInfo( 1<<2, 1<<10, 1<<19),GroupInfo( 1<<2, 1<<11, 1<<19),GroupInfo( 1<<2, 1<<12, 1<<19),GroupInfo( 1<<2, 1<<13, 1<<20),GroupInfo( 1<<2, 1<<14, 1<<20),GroupInfo( 1<<2, 1<<15, 1<<20),GroupInfo( 1<<2, 1<<16, 1<<21),GroupInfo( 1<<2, 1<<17, 1<<21),GroupInfo( 1<<2, 1<<18, 1<<21),

GroupInfo( 1<<3, 1<<10, 1<<19),GroupInfo( 1<<3, 1<<11, 1<<19),GroupInfo( 1<<3, 1<<12, 1<<19),GroupInfo( 1<<3, 1<<13, 1<<20),GroupInfo( 1<<3, 1<<14, 1<<20),GroupInfo( 1<<3, 1<<15, 1<<20),GroupInfo( 1<<3, 1<<16, 1<<21),GroupInfo( 1<<3, 1<<17, 1<<21),GroupInfo( 1<<3, 1<<18, 1<<21),

GroupInfo( 1<<4, 1<<10, 1<<22),GroupInfo( 1<<4, 1<<11, 1<<22),GroupInfo( 1<<4, 1<<12, 1<<22),GroupInfo( 1<<4, 1<<13, 1<<23),GroupInfo( 1<<4, 1<<14, 1<<23),GroupInfo( 1<<4, 1<<15, 1<<23),GroupInfo( 1<<4, 1<<16, 1<<24),GroupInfo( 1<<4, 1<<17, 1<<24),GroupInfo( 1<<4, 1<<18, 1<<24),

GroupInfo( 1<<5, 1<<10, 1<<22),GroupInfo( 1<<5, 1<<11, 1<<22),GroupInfo( 1<<5, 1<<12, 1<<22),GroupInfo( 1<<5, 1<<13, 1<<23),GroupInfo( 1<<5, 1<<14, 1<<23),GroupInfo( 1<<5, 1<<15, 1<<23),GroupInfo( 1<<5, 1<<16, 1<<24),GroupInfo( 1<<5, 1<<17, 1<<24),GroupInfo( 1<<5, 1<<18, 1<<24),

GroupInfo( 1<<6, 1<<10, 1<<22),GroupInfo( 1<<6, 1<<11, 1<<22),GroupInfo( 1<<6, 1<<12, 1<<22),GroupInfo( 1<<6, 1<<13, 1<<23),GroupInfo( 1<<6, 1<<14, 1<<23),GroupInfo( 1<<6, 1<<15, 1<<23),GroupInfo( 1<<6, 1<<16, 1<<24),GroupInfo( 1<<6, 1<<17, 1<<24),GroupInfo( 1<<6, 1<<18, 1<<24),

GroupInfo( 1<<7, 1<<10, 1<<25),GroupInfo( 1<<7, 1<<11, 1<<25),GroupInfo( 1<<7, 1<<12, 1<<25),GroupInfo( 1<<7, 1<<13, 1<<26),GroupInfo( 1<<7, 1<<14, 1<<26),GroupInfo( 1<<7, 1<<15, 1<<26),GroupInfo( 1<<7, 1<<16, 1<<27),GroupInfo( 1<<7, 1<<17, 1<<27),GroupInfo( 1<<7, 1<<18, 1<<27),

GroupInfo( 1<<8, 1<<10, 1<<25),GroupInfo( 1<<8, 1<<11, 1<<25),GroupInfo( 1<<8, 1<<12, 1<<25),GroupInfo( 1<<8, 1<<13, 1<<26),GroupInfo( 1<<8, 1<<14, 1<<26),GroupInfo( 1<<8, 1<<15, 1<<26),GroupInfo( 1<<8, 1<<16, 1<<27),GroupInfo( 1<<8, 1<<17, 1<<27),GroupInfo( 1<<8, 1<<18, 1<<27),

GroupInfo( 1<<9, 1<<10, 1<<25),GroupInfo( 1<<9, 1<<11, 1<<25),GroupInfo( 1<<9, 1<<12, 1<<25),GroupInfo( 1<<9, 1<<13, 1<<26),GroupInfo( 1<<9, 1<<14, 1<<26),GroupInfo( 1<<9, 1<<15, 1<<26),GroupInfo( 1<<9, 1<<16, 1<<27),GroupInfo( 1<<9, 1<<17, 1<<27),GroupInfo( 1<<9, 1<<18, 1<<27)

bool AI(std::vector<Item>& game)

for(size_t x= 0; x< game.size();++x){

if( 0!= game[x].data){//依次检查每个位置

vTemp.push_back( game[i].data);

vTemp.erase( std::remove(vTemp.begin(),vTemp.end(), 0), vTemp.end());

for(std::vector<int>::iterator Iter= vTemp.begin(); Iter!=vTemp.end();++ Iter)

std::replace(game[x].other.begin(), game[x].other.end(),(*Iter), 0);

game[x].other.erase( std::remove(game[x].other.begin(),game[x].other.end(), 0),game[x].other.end());

if(( 1== game[x].other.size())&&( 0!= game[x].other[0])){

game[x].data= game[x].other[0];

{return( item.other.size()==2)?true:false;}

if(( item.data==0)&&(item.other.size()==0))

bool AdvanceAI(std::vector<Item>& game)

std::vector<Item> Back= game;

std::vector<Item>::iterator iItem= std::find_if( Back.begin(), Back.end(), OtherIs2Opt());

for(size_t i= 0; i<(*iItem).other.size();++i){

if( std::for_each( Back.begin(), Back.end(), testBackOpt()).bBack){//是否结束回滚

iItem= std::find_if( Back.begin(), Back.end(), OtherIs2Opt());

if( std::count( Back.begin(), Back.end(), 0)){//判断是否结束

if( AdvanceAI( Back)){//没有结束,继续下一步递归

iItem= std::find_if( Back.begin(), Back.end(), OtherIs2Opt());

int main(int argc, char* argv[])

std::vector<Item> game(SIZE);

std::copy(Data,Data+SIZE, game.begin());

if( std::count( game.begin(), game.end(), 0)){

return 0;算法如下,先构造一个9*9的结构体数组,表示棋盘数据0表示空白未知,结构体中每个元素

包含一个1-9的数组作为备选数字.

构建好一个棋盘之后依次对每个空白位置进行备选数字中进行删除.当前已经填写的数字就全部删除

如果只剩下一个备选数字就将该备选数字填写到棋盘数据中.该算法在AI这个函数中实现.

当无法用AI算法推出结果的时候就进行回朔法,见找到有两个备选数字的元素,选取其中一个,

继续往下填写,直到全部填写上去(结束),或者无法继续填写(某个空白位置没有备选元素).

如果无法继续填写下去就表示最初选择的那个数据是错误的,直接填写另外一个数据到棋盘上.

如此下去就能够填写出棋盘中的所有元素.

unsigned int Data[SIZE]={//未解棋盘数据

const int temp[9]={ 1, 2, 3, 4, 5, 6, 7, 8, 9};

Item():data(0),other(temp,temp+9){}

inline Item& operator=(const Item& src)

inline Item& operator=(int x){

std::copy(temp,temp+sizeof(temp)/sizeof(temp[0]), other.begin());

inline operator int(){return data;}

const int Group1,Group2,Group3;

GroupInfo(int g1,int g2,int g3):Group1(g1),Group2(g2),Group3(g3){}

inline bool operator==(GroupInfo& src){

return((Group1|Group2|Group3)&(src.Group1|src.Group2|src.Group3))?true:false;

GroupInfo( 1<<1, 1<<10, 1<<19),GroupInfo( 1<<1, 1<<11, 1<<19),GroupInfo( 1<<1, 1<<12, 1<<19),GroupInfo( 1<<1, 1<<13, 1<<20),GroupInfo( 1<<1, 1<<14, 1<<20),GroupInfo( 1<<1, 1<<15, 1<<20),GroupInfo( 1<<1, 1<<16, 1<<21),GroupInfo( 1<<1, 1<<17, 1<<21),GroupInfo( 1<<1, 1<<18, 1<<21),

GroupInfo( 1<<2, 1<<10, 1<<19),GroupInfo( 1<<2, 1<<11, 1<<19),GroupInfo( 1<<2, 1<<12, 1<<19),GroupInfo( 1<<2, 1<<13, 1<<20),GroupInfo( 1<<2, 1<<14, 1<<20),GroupInfo( 1<<2, 1<<15, 1<<20),GroupInfo( 1<<2, 1<<16, 1<<21),GroupInfo( 1<<2, 1<<17, 1<<21),GroupInfo( 1<<2, 1<<18, 1<<21),

GroupInfo( 1<<3, 1<<10, 1<<19),GroupInfo( 1<<3, 1<<11, 1<<19),GroupInfo( 1<<3, 1<<12, 1<<19),GroupInfo( 1<<3, 1<<13, 1<<20),GroupInfo( 1<<3, 1<<14, 1<<20),GroupInfo( 1<<3, 1<<15, 1<<20),GroupInfo( 1<<3, 1<<16, 1<<21),GroupInfo( 1<<3, 1<<17, 1<<21),GroupInfo( 1<<3, 1<<18, 1<<21),

GroupInfo( 1<<4, 1<<10, 1<<22),GroupInfo( 1<<4, 1<<11, 1<<22),GroupInfo( 1<<4, 1<<12, 1<<22),GroupInfo( 1<<4, 1<<13, 1<<23),GroupInfo( 1<<4, 1<<14, 1<<23),GroupInfo( 1<<4, 1<<15, 1<<23),GroupInfo( 1<<4, 1<<16, 1<<24),GroupInfo( 1<<4, 1<<17, 1<<24),GroupInfo( 1<<4, 1<<18, 1<<24),

GroupInfo( 1<<5, 1<<10, 1<<22),GroupInfo( 1<<5, 1<<11, 1<<22),GroupInfo( 1<<5, 1<<12, 1<<22),GroupInfo( 1<<5, 1<<13, 1<<23),GroupInfo( 1<<5, 1<<14, 1<<23),GroupInfo( 1<<5, 1<<15, 1<<23),GroupInfo( 1<<5, 1<<16, 1<<24),GroupInfo( 1<<5, 1<<17, 1<<24),GroupInfo( 1<<5, 1<<18, 1<<24),

GroupInfo( 1<<6, 1<<10, 1<<22),GroupInfo( 1<<6, 1<<11, 1<<22),GroupInfo( 1<<6, 1<<12, 1<<22),GroupInfo( 1<<6, 1<<13, 1<<23),GroupInfo( 1<<6, 1<<14, 1<<23),GroupInfo( 1<<6, 1<<15, 1<<23),GroupInfo( 1<<6, 1<<16, 1<<24),GroupInfo( 1<<6, 1<<17, 1<<24),GroupInfo( 1<<6, 1<<18, 1<<24),

GroupInfo( 1<<7, 1<<10, 1<<25),GroupInfo( 1<<7, 1<<11, 1<<25),GroupInfo( 1<<7, 1<<12, 1<<25),GroupInfo( 1<<7, 1<<13, 1<<26),GroupInfo( 1<<7, 1<<14, 1<<26),GroupInfo( 1<<7, 1<<15, 1<<26),GroupInfo( 1<<7, 1<<16, 1<<27),GroupInfo( 1<<7, 1<<17, 1<<27),GroupInfo( 1<<7, 1<<18, 1<<27),

GroupInfo( 1<<8, 1<<10, 1<<25),GroupInfo( 1<<8, 1<<11, 1<<25),GroupInfo( 1<<8, 1<<12, 1<<25),GroupInfo( 1<<8, 1<<13, 1<<26),GroupInfo( 1<<8, 1<<14, 1<<26),GroupInfo( 1<<8, 1<<15, 1<<26),GroupInfo( 1<<8, 1<<16, 1<<27),GroupInfo( 1<<8, 1<<17, 1<<27),GroupInfo( 1<<8, 1<<18, 1<<27),

GroupInfo( 1<<9, 1<<10, 1<<25),GroupInfo( 1<<9, 1<<11, 1<<25),GroupInfo( 1<<9, 1<<12, 1<<25),GroupInfo( 1<<9, 1<<13, 1<<26),GroupInfo( 1<<9, 1<<14, 1<<26),GroupInfo( 1<<9, 1<<15, 1<<26),GroupInfo( 1<<9, 1<<16, 1<<27),GroupInfo( 1<<9, 1<<17, 1<<27),GroupInfo( 1<<9, 1<<18, 1<<27)

bool AI(std::vector<Item>& game)

for(size_t x= 0; x< game.size();++x){

if( 0!= game[x].data){//依次检查每个位置

vTemp.push_back( game[i].data);

vTemp.erase( std::remove(vTemp.begin(),vTemp.end(), 0), vTemp.end());

for(std::vector<int>::iterator Iter= vTemp.begin(); Iter!=vTemp.end();++ Iter)

std::replace(game[x].other.begin(), game[x].other.end(),(*Iter), 0);

game[x].other.erase( std::remove(game[x].other.begin(),game[x].other.end(), 0),game[x].other.end());

if(( 1== game[x].other.size())&&( 0!= game[x].other[0])){

game[x].data= game[x].other[0];

{return( item.other.size()==2)?true:false;}

if(( item.data==0)&&(item.other.size()==0))

bool AdvanceAI(std::vector<Item>& game)

std::vector<Item> Back= game;

std::vector<Item>::iterator iItem= std::find_if( Back.begin(), Back.end(), OtherIs2Opt());

for(size_t i= 0; i<(*iItem).other.size();++i){

if( std::for_each( Back.begin(), Back.end(), testBackOpt()).bBack){//是否结束回滚

iItem= std::find_if( Back.begin(), Back.end(), OtherIs2Opt());

if( std::count( Back.begin(), Back.end(), 0)){//判断是否结束

if( AdvanceAI( Back)){//没有结束,继续下一步递归

iItem= std::find_if( Back.begin(), Back.end(), OtherIs2Opt());

int main(int argc, char* argv[])

std::vector<Item> game(SIZE);

std::copy(Data,Data+SIZE, game.begin());

if( std::count( game.begin(), game.end(), 0)){