数独源代码

#include<iostream>

#include<iomanip>

using namespace std;

#define MaxSize 81    //用于表示队列的长度



class Grid

{

public:

	Grid(int i=0x000901FF):item(i){}

	int getNum(){ return (item>>16); }      //返回这个Grid的可能值的个数

	int getItem(){ return (item&0x0000FFFF); }

	int ItemtoNum() { 

		int i;

		int temp = item;

		for(i=0; i<8 ; i++)

		{

			if(temp&0x1)

				break;

			temp>>=1;

		}

		return (i+1)%10;

	}



	int del(int i){ item&=~int(i); return _setNum(); }  //注意这里的i为二进制形式

	int add(int i){ item|= int(i); return _setNum(); }  //注意这里的i为二进制形式

	int set(int i){ item=0; return add(i); }            //i同上, 这个函数用于设置数值



private:

	int item;

	int _setNum() {       //数出可能值的个数, 并赋值

		int temp = item;

		int r = temp&0x1;

		for(int i=0; i<8; i++){

			temp>>=1;

			r += temp&0x1;

		}

		item&=0x0000FFFF;

		item|= r<<16;

		return r;

	}

};



class JiugongGe

{

public:

	JiugongGe(Grid* igrd=NULL){

		if(igrd!=NULL)

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

				grd[i] = igrd[i];

				if(grd[i].getNum() == 1){ //设置表

//				setJiugongGe(i);

				}

			}

	}

	Grid& getGrid(int i, int j){ return grd[i*3+j]; }  //用于大九宫格的寻址

	Grid& getGrid(int i) { return grd[i]; }

	//void setJiugongGe(int i){

	//	item+=0x00010000;     //数字加一

	//	item|=int(1<<(i-1));	  //表明位置;

	//}



private:

//	int item;      //去除

	Grid grd[9];   

};



template<class T>

class Queue          // 用于存放Grid的一些信息

{

public:

	Queue():size(0){}

	void Enter(T t){ item[size++] = t; }

	T operator[](int i) { if(i>=0 && i<size) return item[i]; }

	int getSize() { return size; }

	void clear() { size=0; }

private:

	int size;

	T item[MaxSize];

};

///消息结构

struct Info

{

	int px;

	int py;

	int	item;

	Info(int i=-1, int j=-1, int n=-1):px(i), py(j), item(n){}

};

class Sudoku

{

public:

	Sudoku(Sudoku* sdk=NULL){

		if(sdk!=NULL){

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

				jgg[i] = sdk->jgg[i];

			}

		}

		else{

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

				jgg[i] = new JiugongGe;

		}

	}

	~Sudoku(){

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

			delete jgg[i];

	}

	Grid** getLine(int type, int n)

	{

		Grid** temp = new Grid*[9]; 

		switch(type)

		{

		case 1:

			for(int i=0; i<3; i++){

				for(int j=0; j<3; j++){

					temp[i*3+j] = &jgg[3*(n/3)+i]->getGrid(n%3,j);

				}

			}

			break;

		case 2:

			for(int i=0; i<3; i++){

				for(int j=0; j<3; j++){

					temp[i*3+j] = &jgg[n/3+i*3]->getGrid(j,n%3);

				}

			}

			break;

		case 3:

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

				temp[i] = &jgg[n]->getGrid(i);

			break;

		}

		return temp;

	}

	Grid& getGrid(int i, int j)

	{

		return jgg[3*(i/3)+j/3]->getGrid(i%3, j%3);

	}

	void setGrid(int i, int j, int value)   //value 为数字

	{

		getGrid(i, j).set(int(1)<<(value-1));

	}

	void setGrid(int type, int n, int i, int value)  //value 为数字

	{

		switch(type)

		{

		case 1:

			setGrid(n, i, value);

			break;

		case 2:

			setGrid(i, n, value);

			break;

		case 3:

			setGrid(3*(n/3)+i/3, 3*(n%3)+i%3, value);

			break;

		}

	}

	void run()

	{

		//程序的初始化, 用于查找确定的Grid, 同时填写信息队列

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

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

				Grid temp = getGrid(i,j);

				if(temp.getNum()==1)

					info.Enter(Info(i,j,temp.getItem()));

			}

		}

		//初始化结束, 进行运行, 从信息队列中取出信息,

		//然后设置影响的行列及九宫格,同时填写信息队列

		while(info.getSize()){

			while(info.getSize()){

				Queue<Info> T_info = info;

				info.clear();



				for( int type=1; type<=3; type++){

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

						int item;

						if(item = getDelItem(T_info, type, i))

							del(type, i, item);

					}

				}

			}



			//	Grid testt = getGrid(5,1);

			//	Grid& testt = getGrid(0,3);



			//需求处理

			for(int type=1; type<=3; type++){

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

					makeItem(type, i);



				}

			}

		}

	}



	void del(int type, int n, int item)

	{

		Grid** grid = getLine(type, n);

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

			if(grid[i]->getNum() == 1)

				continue;

			if(grid[i]->del(item) == 1)

				EnterInfo(type, n, i, grid[i]->getItem());

		}

	}

	/* **************************************************

	 * 函数功能: 在给定的一个数组中,根据需求法确定元素,

	 *             并存入Info数组;

	 *

	 * 参数说明: type  : 1 表示行

	 *					: 2 表示列

	 *					: 3 九宫格

	 *			  num   表示第几 行、列、九宫格

	 *			  grid  传入的数组

	 *

	 ****************************************************/

	void makeItem(int type, int num )

	{

		///test

	//	Grid& testt = getGrid(5,1);

		Grid** grid = getLine(type, num);

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

			int f = int(1)<<i;

			int n=0, k=0;

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

				if(grid[j]->getItem()&f){

					k=j;

					n++;

				}

			}

			if( n==0)

				exit(1);       //出错啦!、、、、、、、、、、、、、、、、、

			if( n==1 && grid[k]->getNum()!=1 )

			{

				setGrid(type, num, k, i+1);  //此中的i+1应为数字, 而非符号

				EnterInfo(type, num, k, f);  //此中 f 为符号

			}

		}

	}

	void EnterInfo(int type, int n, int i, int item)

	{

		switch (type)

		{

		case 1:

			info.Enter(Info(n, i, item));

			break;

		case 2:

			info.Enter(Info(i, n, item));

			break;

		case 3:

			info.Enter(Info(3*(n/3)+i/3, 3*(n%3)+i%3, item));

			break;

		}

	}



	/* **************************************************

	 * 函数功能: 在Queue中获取 行、列、九宫格中相应要

	 *			  减去的项

	 * 参数说明: type  : 1 表示行

	 *					: 2 表示列

	 *					: 3 九宫格

	 *			  num   表示第几 行、列、九宫格

	 *

	 ****************************************************/

	int getDelItem(Queue<Info>& info,int type, int num)

	{

		int r;

		switch(type)

		{

		case 1:

			r=getRowItem(info, num);

			break;

		case 2:

			r=getColumnItem(info, num);

			break;

		case 3:

			r=getJiugongGeItem(info, num);

			break;

		}

		return r;

	}

	int getRowItem(Queue<Info>& info, int num)

	{

		int r=0;

		for(int i=0; i<info.getSize(); i++){

			Info temp = info[i];

			if(temp.px == num)

				r |= temp.item;

		}

		return r;

	}

	int getColumnItem(Queue<Info>& info, int num)

	{

		int r=0;

		for(int i=0; i<info.getSize(); i++){

			Info temp = info[i];

			if(temp.py == num)

				r |= temp.item;

		}

		return r;

	}

	int getJiugongGeItem(Queue<Info>& info, int num)

	{

		int r=0;

		for(int i=0; i<info.getSize(); i++){

			Info temp = info[i];

			if(temp.px>=3*(num/3) && temp.px<3*(num/3+1) 

				&& temp.py>=3*(num%3) && temp.py<3*(num%3+1))

				r |= temp.item;

		}

		return r;

	}

	//运行九宫格

	void print();

private:

	Queue<Info> info;   //用于存放确定的Grid 的信息

//	int cItem[9], rItem[9];   //去除

	JiugongGe* jgg[9];

};



void Sudoku::print()

{

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

		Grid** temp = getLine(1,i);

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

			cout << setw(2) <<  ((temp[j]->getNum()==1) ? temp[j]->ItemtoNum(): 0);

		cout << endl;

	}

}







///test/

void test()

{

	Sudoku jw;

	/*jw.setGrid(0,2,3);

	jw.setGrid(0,4,5);

	jw.setGrid(0,7,1);

	jw.setGrid(1,2,8);

	jw.setGrid(1,4,7);

	jw.setGrid(1,6,3);

	jw.setGrid(2,1,2);

	jw.setGrid(2,4,3);

	jw.setGrid(3,1,1);

	jw.setGrid(3,3,9);

	jw.setGrid(3,5,2);

	jw.setGrid(3,8,4);

	jw.setGrid(4,2,6);

	jw.setGrid(4,4,8);

	jw.setGrid(4,6,1);

	jw.setGrid(5,0,2);

	jw.setGrid(5,5,4);

	jw.setGrid(5,7,3);

	jw.setGrid(6,4,4);

	jw.setGrid(6,7,5);

	jw.setGrid(7,2,7);

	jw.setGrid(7,4,9);

	jw.setGrid(7,6,8);

	jw.setGrid(8,1,6);

	jw.setGrid(8,4,2);

	jw.setGrid(8,6,9);

	jw.setGrid(0, 1, 4);

	jw.setGrid(0, 3, 2);

	jw.setGrid(0, 6, 8);

	jw.setGrid(1, 2, 1);

	jw.setGrid(1, 6, 9);

	jw.setGrid(2, 0, 6);

	jw.setGrid(2, 5, 4);

	jw.setGrid(3, 2, 6);

	jw.setGrid(3, 4, 1);

	jw.setGrid(3, 7, 7);

	jw.setGrid(4, 0, 1);

	jw.setGrid(4, 4, 2);

	jw.setGrid(4, 8, 4);

	jw.setGrid(5, 1, 7);

	jw.setGrid(5, 6, 3);

	jw.setGrid(6, 3, 7);

	jw.setGrid(6, 8, 3);

	jw.setGrid(7, 2, 8);

	jw.setGrid(7, 6, 2);

	jw.setGrid(8, 2, 5);

	jw.setGrid(8, 5, 3);

	jw.setGrid(8, 7, 9);*/

//	jw.print();



	jw.setGrid(0,0,6);

	jw.setGrid(0,4,9);

	jw.setGrid(0,6,1);

	jw.setGrid(0,8,4);

	jw.setGrid(1,0,1);

	jw.setGrid(1,1,9);

	jw.setGrid(1,3,7);

	jw.setGrid(1,6,2);

	jw.setGrid(2,1,8);

	jw.setGrid(2,3,4);

	jw.setGrid(2,4,3);

	jw.setGrid(2,6,5);

	jw.setGrid(3,2,6);

	jw.setGrid(3,4,2);

	jw.setGrid(3,5,7);

	jw.setGrid(3,6,3);

	jw.setGrid(3,8,1);

	jw.setGrid(4,2,7);

	jw.setGrid(4,5,4);

	jw.setGrid(4,6,9);

	jw.setGrid(5,0,3);

	jw.setGrid(5,2,8);

	jw.setGrid(5,5,5);

	jw.setGrid(5,6,4);

	jw.setGrid(6,2,9);

	jw.setGrid(6,4,7);

	jw.setGrid(6,5,2);

	jw.setGrid(6,7,1);

	jw.setGrid(7,2,1);

	jw.setGrid(7,5,9);

	jw.setGrid(7,7,4);

	jw.setGrid(7,8,5);

	jw.setGrid(8,0,8);

	jw.setGrid(8,2,5);

	jw.setGrid(8,4,4);

	jw.setGrid(8,8,2);

	jw.run();

	jw.print();

	

//	jw.run();

}

void main()

{

	test();

	/*Grid jw(0x30007);

	cout << jw.getNum() << "  " << jw.getItem() << endl;

	jw.del(2);

	cout << jw.getNum() << "  " << jw.getItem();*/

}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值