【问题标题】:Character / int equality evaluating incorrectly字符/整数相等评估不正确
【发布时间】: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 &lt;&lt; (int) get(g,r,y)char 的流输出运算符被重载,因此它输出一个字符而不是实际值。

标签: c++ arrays boolean


【解决方案1】:

这个:

if(get(g,r,y) - 0 == i - 0) 

不起作用。如果 get 返回一个字符,它是一个字符串中的一个字符,表示数字的 CODE。你从中减去一个整数 0,这并没有减去任何东西。你想要的要么是

if(get(g,r,y) - '0' == i)

或者

if(get(g,r,y) == i + '0')

假设 ascii(不是 unicode 或其他)。

您尝试做的是在 ascii CHARACTER 和整数之间“转换”。您将转换为一个或另一个,而不是两者。 0 和 '0' 的区别在于第一个是整数零,第二个是字符串中的 0 字符。

【讨论】:

  • 谢谢!我误读了另一篇文章的答案,这是我得到减去 0 的信息的地方。我知道这是一个错字
【解决方案2】:
(get(g,r,y) - 0 == i - 0);

这是错误的。改用它。

(get(g,r,y) - '0' == i - 0);

【讨论】:

  • 谢谢!这是正确的,尽管给出的其他答案提供了更多信息,所以我将其标记为正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
相关资源
最近更新 更多