1 Star 0 Fork 0

alanlovesy/SuDuKu

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
SD_class_Tool.cpp 6.33 KB
一键复制 编辑 原始数据 按行查看 历史
alanlovesy 提交于 2018-06-26 15:36 . 修改挖空策略
//SD_C_Tool.cpp---------------数独类中工具方法的定义
//
// void SD_C::Init_q(): //用全局数组q1初始化q
// void SD_C::Init_s(); //初始化
// void SD_C::SimpleInit_s(); //简单初始化
// void SD_C::Print_q(int); //打印结果数组q
// void SD_C::Out_q(); //输出数组q到全局数组q0中
//
// int SD_C::CountOneBit(short); //计算二进制数中1的个数
// int SD_C::HighestOneBit(short); //取最高位1的位数
// void SD_C::Print_bit(short); //打印九位二进制数
//
// void SD_C::Print_s(); //打印s数组当前状态
// int SD_C::Check_s(); //检查s数组解题进度
// void SD_C::Update_q(); //通过s数组更新答题数组q
//
//v.1.0------------------------------------------------------------------
#include<iostream>
#include<cmath>
#include"SD_class.h"
#include"SD_ver.h"
using namespace std;
//1.初始化q
void SD_C::Init_q()
{
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
q[i][j] = q4[i][j];
}
//2.初始化s
void SD_C::Init_s()
{
cout << "开始初始化";
//根据数组q的初始值初始化数组s
//Print_s();
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (q[i][j] == 0)
s[i][j] = 511; //二进制为0b1 1111 1111
else
s[i][j] = 1 << (q[i][j] - 1);
cout<<"-";
}
}
//对数组s进行去重操作(运用唯一法)
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
FindSole(i, j); //去重
cout<<"-";
}
t = 0; //重置解个数存储器
//打印数独题目
cout <<"初始化结束"<<endl;
//<<"目前数组标志状态:"<<endl;
//Print_s();
//cout<<"目前数组填空状态:"<<endl;
//Print_q(1);
//cout<<"-------------------------------------------------------------------------------------------------------------------------"<<endl;
}
//3.简单初始化数组s并打印
void SD_C::SimpleInit_s()
{
//cout << "开始简单初始化"<<endl;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (q[i][j] == 0)
s[i][j] = 511;
else
s[i][j] = 1 << (q[i][j] - 1);
//cout<<"-";
}
}
t = 0; //重置解个数存储器
//cout <<"简单初始化结束"<<endl;
}
//4.打印结果数组q
void SD_C::Print_q(int a)
{
int Block = 0;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
cout << q[i][j];
if (j == 2 || j == 5)
cout << " ";
if (j == 8)
{
cout << endl;
if (i == 2 || i == 5)
cout << endl;
}
if (q[i][j] == 0)
Block++;
}
}
if (a)
cout << "已知" << 81 - Block << "个空。"<<endl<<endl;
}
//5.输出结果q到全局数组q0
void SD_C::Out_q()
{
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
q0[i][j] = this->q[i][j];
}
//6.计算二进制数中1的个数
int SD_C::CountOneBit(short a)
{
int n = 0;
while (a) {
n++;
a &= (a - 1);
}
return n;
}
//7.取二进制数最高位1的位数
// 第次右移,得到从高位开始的
// 一串1,再减去自身右移一位
// 后的数,得到仅高位有1的数
int SD_C::HighestOneBit(short a)
{
a |= (a >> 1);
a |= (a >> 2);
a |= (a >> 4);
a |= (a >> 8);
return a - (a >> 1);
}
//8.打印9位二进制数
void SD_C::Print_bit(short a)
{
short b;
for (int i = 8; i >= 0; i--)
{
b = a & (1 << i);
if (b == 0)
cout << 0;
else
cout << 1;
}
//cout << " ";
}
//9.打印当前数独解题状态
void SD_C::Print_s()
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
Print_bit(s[i][j]);
cout<<"-"<<q[i][j]<<" ";
if (j == 2 || j == 5)
cout << " ";
if (j == 8)
{
cout << endl;
if (i == 2 || i == 5 || i == 8)
cout << endl;
}
}
}
cout << endl;
}
//10.检查解题进度
// @return 0 完成
// 1 未完成
// -1 出错
int SD_C::Check_s()
{
//cout<<"check"<<endl;
//可选判断
for (int j = 0; j < 9; j++)
for (int i = 0; i < 9; i++)
if (s[i][j] == 0)
{
//cout<<"候选数为0,出错!"<<endl;
return -1;
}
short sum_row; //行
short sum_col; //列
short sum_squ; //宫
for (int i = 0; i < 9; i++)
{
sum_row = sum_col = sum_squ = 0;
//行、列(row\col)
for (int j = 0; j < 9; j++)
{
//累加9个空的候选数,结果应当为0b1 1111 1111
sum_row |= s[i][j]; //i行
sum_col |= s[j][i]; //i列
}
//宫(squ)
for (int i0 = i / 3 * 3; i0 < i / 3 * 3 + 3; i0++)
for (int j0 = i % 3 * 3; j0 < i % 3 * 3 + 3; j0++)
sum_squ |= s[i0][j0]; //i宫
if (sum_row != 0x1ff || sum_col != 0x1ff || sum_squ != 0x1ff)
{
// cout<<"第"<<i+1<<"列:";
// Print_bit(sum_col);
// cout<<endl<<"第"<<i+1<<"行:";
// Print_bit(sum_row);
// cout<<endl<<"第"<<i+1<<"宫:";
// Print_bit(sum_squ);
// cout<<endl<<"填空出错,和不为1 1111 1111"<<endl;
return -1; //有一个不为0b1 1111 1111,即0x1ff,表示出错
}
}
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (CountOneBit(s[i][j]) > 1)
{
//cout<<"候选数多于1,未完成"<<endl;
return 1;
}
}
}
//cout<<"完成!"<<endl;
return 0; //排除以上所有情况后,表示所有空都填完了
}
//11.通过数组s更新数组q
void SD_C::Update_q()
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
switch (s[i][j])
{
case 1: {q[i][j] = 1;break;} //单个候选数
case 2: {q[i][j] = 2;break;}
case 4: {q[i][j] = 3;break;}
case 8: {q[i][j] = 4;break;}
case 16: {q[i][j] = 5;break;}
case 32: {q[i][j] = 6;break;}
case 64: {q[i][j] = 7;break;}
case 128: {q[i][j] = 8;break;}
case 256: {q[i][j] = 9;break;}
case 0: {q[i][j] = -1;break;} //出错,无候选数
default: {q[i][j] = 0;break;} //多个候选数
}
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/alanlovesy/sd.git
git@gitee.com:alanlovesy/sd.git
alanlovesy
sd
SuDuKu
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385