【发布时间】:2015-09-14 02:05:31
【问题描述】:
背景信息:我正在编写一个 C++ 程序来解决数独难题,但我遇到了一个主要障碍。程序的大致流程是这样的:
- 遍历网格并检查是否可以用数字替换 0。 (空格用 0 表示)
- 检查 3 个维度(垂直、水平和框内)哪些数字已经存在。
- 确定我们是否可以将该数字缩小到一种可能性,替换它,然后继续。
- 重复直到网格没有零
我在第二步遇到问题,我会将整个程序发布在底部,但这里只发布相关代码。
int* check_v(string g, size_t x, size_t y){
int *ans = new int[9]; //array of possible ints
memset(ans, 0, sizeof(ans)); //set array to all 0s
size_t size = 0;
for(int i = 1; i < 10; i++){ //iterate through 1-10
//check if i is in the col, if it isn't then add i to ans
bool placeable = true;
for(size_t j = 0; j < 9; j++){ //iterate through ints in the col
size_t r = (j + x) % 9; //the string is a 9x9 grid of numbers
cout << get(g,r,y) << " == " << i << " is " << (get(g,r,y) - 0 == i - 0);
//this is my debug statement, because the if below isn't working.
if(get(g,r,y) - 0 == i - 0){ //if i is equal to a num in the grid,
placeable = false;//we know it can't be that number
}
}
if(placeable) ans[size++] = i; //only add i if we didn't find it in the grid
}
return ans;
}
这是检查每个数字的列以查看哪些数字存在/不存在的方法之一。
下面是相关的get()方法:
char get(string g, size_t x, size_t y){
return g.at(x * 9 + y);
}
其中 g 是 0-9 81 个字母长的数字字符串。这是一个 9x9 的网格,但放入一根长字符串中。
所以 get(g,r,y) 返回一个类似于 '6' 的字符,而 i 是一个 int。我做 '6' - 0 使它们都是整数,并比较它们。然而,总是假的!即使 i = 6 并且 get(g,r,y) = '6'。我做的比较错了吗?我一定有一个错字,我只是没有看到它。这是该 cout 调用的一些示例输出,我将发布整个文件以获取上下文。
//output
0 == 1 is 0
3 == 1 is 0
8 == 1 is 0
2 == 1 is 0
5 == 1 is 0
7 == 1 is 0
4 == 1 is 0
9 == 1 is 0
6 == 1 is 0 //this is all right, there aren't any 1s in the col
0 == 2 is 0
3 == 2 is 0
8 == 2 is 0
2 == 2 is 0 //but this is wrong! why isn't this true?
5 == 2 is 0
7 == 2 is 0
4 == 2 is 0
9 == 2 is 0
6 == 2 is 0
现在这是整个文件,为您提供全貌。
using namespace std;
#include <iostream>
#include <cstring>
void print(string g){
for(size_t i = 0; i < 9; i++){
for(size_t j = 0; j < 9; j++){
cout << g.at(i * 9 + j);
}
cout << endl;
}
}
void set(string & g, size_t x, size_t y, char z){
size_t i = x * 9 + y;
string beg = g.substr(0,i);
string end = g.substr(i+1,g.length());
g = beg + z + end;
}
char get(string g, size_t x, size_t y){
return g.at(x * 9 + y);
}
int* check_v(string g, size_t x, size_t y){
int *ans = new int[9];
memset(ans, 0, sizeof(ans));
size_t size = 0;
for(int i = 1; i < 10; i++){
bool placeable = true;
for(size_t j = 0; j < 9; j++){
size_t r = (j + x) % 9;
cout << get(g,r,y) << " == " << i << " is " << (get(g,r,y) - 0 == i - 0) << endl;
if(get(g,r,y) - 0 == i - 0){
placeable = false;
}
}
if(placeable) ans[size++] = i;
}
return ans;
}
int* check_b(string g, size_t x, size_t y){
int *ans = new int[9];
memset(ans, 0, sizeof(ans));
size_t size = 0;
x = x / 3 * 3;
y = y / 3 * 3;
for(size_t i = 0; i < 3; i++){
bool placeable = true;
for(size_t j = 0; j < 3; j++)
if(get(g,x + i, y + j) == static_cast<char>(i))
placeable = false;
if(placeable) ans[size++] = i;
}
return ans;
}
int* check_h(string g, size_t x, size_t y){
int *ans = new int[9];
memset(ans, 0, sizeof(ans));
size_t size;
for(size_t i = 1; i < 10; i++){
bool placeable = true;
for(size_t j = 0; j < 9; j++){
cout << get(g,x,(j + y) % 9) << " == " << i << endl;
if(get(g,x,(y + j) % 9) == static_cast<char>(i)){
placeable = false;
}
}
if(placeable) ans[size++] = i;
}
return ans;
}
void check(string g, size_t x, size_t y){
int *n_v = check_v(g, x, y);
int *n_h = check_h(g, x, y);
int *n_b = check_b(g, x, y);
int n_y[9] = {0};
int n;
size_t size = 0;
cout << "vert: ";
for (int i = 0; i < 9; i++)
cout << n_v[i];
cout << endl << "hor: ";
for (int i = 0; i < 9; i++)
cout << n_h[i];
cout << endl << "box: ";
for (int i = 0; i < 9; i++)
cout << n_b[i];
cout << endl;
if(n_v[0] == 0 || n_h[0] == 0 || n_b[0] == 0)
cout << "Error, no number works in slot " << x << ", " << y << endl;
else{
if(n_v[1] == 0)
n = n_v[0];
else if(n_h[1] == 0)
n = n_h[0];
else if(n_b[1] == 0)
n = n_b[0];
}
for(size_t i = 0; i < 9; i++){
bool possible = true;
for(size_t j = 0; possible && j < 9; j++){
if(n_h[j] != n_v[i])
possible = false;
}
for(size_t j = 0; possible && j < 9; j++){
if(n_b[j] != n_v[i])
possible = false;
}
if(possible)
n_y[size++] = n_v[i];
}
if(n_y[1] == 0)
n = n_y[0];
if(n != 0){
char c = n;
set(g,x,y,c);
}
}
int main(){
//initializations
size_t dim = 9;
string data = "";
string one_row;
for (size_t r = 0; r < dim ; r = r + 1) {
cin >> one_row;
data += one_row;
}
//start solving
bool cont = true;
while(cont){
cont = false;
for(size_t i = 0; i < data.length(); i ++){
if(data.at(i) == '0'){
cont = true;
cout << "Checking at point " << i / 9 << ", " << i % 9 << endl;
string old = data;
check(data, i / 9, i % 9);
if(old.compare(data) != 0)
print(data);
}
}
}
print(data);
}
【问题讨论】:
-
'6'根本不等同于6。也许你想要get(g,r,y) - '0' == i。在 ASCII 中,'0'的值是 48,而不是 0。 -
int *ans = new int[9];只是没有。你甚至不删除它。至少使用int ans[9] = {}; -
注意:如果您在调试时进行了强制转换,您会发现这个问题:
cout << (int) get(g,r,y)。char的流输出运算符被重载,因此它输出一个字符而不是实际值。