c++ - 输入/输出文件(数独求解器)

标签 c++ c++11 recursion file-io sudoku

首先,我是一名编码初学者,我已经尝试处理和解决我的部分问题数小时,但无法弄清楚。

除了两个任务,我已经完成了所有任务: 1.) 我不知道如何使用 ifstream 和 ofstream 的输入和输出文件机制来获取我的 .txt 文件来设置我的数独板的值。 2.) 我似乎无法弄清楚如何为单元格中每个 xyposition 的每个“可能值”打印出数独板。

我正在尝试实现一个文本文件,内容如下:

  puzzle.setBoardValue(0,0,1);
  puzzle.setBoardValue(1,1,3);
  puzzle.setBoardValue(2,2,9);

  puzzle.setBoardValue(3,2,6);
  puzzle.setBoardValue(4,1,2);
  puzzle.setBoardValue(5,0,7);

  puzzle.setBoardValue(6,2,5);
  puzzle.setBoardValue(7,0,9);
  puzzle.setBoardValue(8,1,8);

  puzzle.setBoardValue(0,5,6);
  puzzle.setBoardValue(1,4,1);
  puzzle.setBoardValue(2,3,5);

  puzzle.setBoardValue(3,3,3);
  puzzle.setBoardValue(4,4,8);
  puzzle.setBoardValue(5,5,4);

  puzzle.setBoardValue(6,3,9);
  puzzle.setBoardValue(8,4,2);

  puzzle.setBoardValue(0,6,3);
  puzzle.setBoardValue(1,7,4);
  puzzle.setBoardValue(2,8,7);

  puzzle.setBoardValue(6,8,3);
  puzzle.setBoardValue(7,6,1);
  puzzle.setBoardValue(8,7,7); `

基本上使用它来自动将我的程序定向到函数 void setBoardValue(); 我所知道的只是在我的 int main(); 中把

cout << "Enter filename:" << endl;
cin >> filename;
in.open(filename);
while(getline(in,line)){
...

其次,我就是不知道如何打印每个数字单元格的所有可能值。

这是我的整个程序代码:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

class SudokuPuzzle{

private:
  unsigned short board[9][9];
  char BlankChar;
  bool debug;
  void printTracerTryingValue(int xpos, int ypos);
  bool solve(int xpos, int ypos);
  bool verifyValue(int xpos, int ypos);

public:
  SudokuPuzzle();
  void print();
  void setBoardValue(int xpos, int ypos, int value);
  int getBoardValue(int xpos, int ypos);
  bool solve();
};

SudokuPuzzle::SudokuPuzzle(){
  debug = false;
  for (int i = 0; i < 9; ++i){
    for (int j = 0; j < 9; ++j){
      board[j][i] = 0;
    }
  }
}

void SudokuPuzzle::print(){
  for (int y = 0; y < 9; y++){
    if (y % 3 == 0){
      cout << "-------------------------------" << endl;
    }
    for (int x = 0; x < 9; x++){
      if (x % 3 == 0){
        cout << "|";
      }
      if (board[x][y] != 0){
        cout << " " << board[x][y] << " ";
      }
      else{
        cout << " . ";
      }
    }
    cout << "|" << endl;
  }
  cout << "-------------------------------" << endl;
}

void SudokuPuzzle::setBoardValue(int xpos, int ypos, int value){
   board[xpos][ypos] = value;
}

void SudokuPuzzle::setBoardValue(int xpos, int ypos, int value){
  board[xpos][ypos] = value;
}

bool SudokuPuzzle::solve(){
  return solve(0,0);
}

void SudokuPuzzle::setBoardValue(int xpos, int ypos, int value){
  board[xpos][ypos] = value;
}

bool SudokuPuzzle::solve(){
  return solve(0,0);
}

int SudokuPuzzle::getBoardValue(int xpos, int ypos){
  return board[xpos][ypos];
}

bool SudokuPuzzle::solve(int xpos, int ypos){
  if (board[xpos][ypos] != 0){
    if (verifyValue(xpos, ypos)){
      if (xpos == 8 && ypos == 8){
        return true;
      }
      int next_x = xpos+1;
      int next_y = ypos;
      if (next_x >= 9){
        next_x = 0;
        next_y++;
      }
      return solve(next_x, next_y);
    }
    else{
      return false;
    }
  }
  for(int value = 1; value < 10; value++){
    setBoardValue(xpos, ypos, value);
    if (verifyValue(xpos, ypos)){
      if (xpos == 8 && ypos == 8){
        return true;
      }
      int next_x = xpos+1;
      int next_y = ypos;

      if (next_x >= 9){
        next_x = 0;
        next_y++;
      }
      if (solve(next_x, next_y)){
        return true;
      }
    }
  }

  board[xpos][ypos] = 0;
  return false;
}
bool SudokuPuzzle::verifyValue(int xpos, int ypos){
  printTracerTryingValue(xpos, ypos);
  int value = board[xpos][ypos];
  for (int x_verify = 0; x_verify < 9; x_verify++){
    if (x_verify == xpos){
      continue;
    }
    int verifyValue = board[x_verify][ypos];
    if (verifyValue == value){
      return false;
    }
  }
  for (int y_verify = 0; y_verify < 9; y_verify++){
    if (y_verify == ypos){
      continue;
    }
    int verifyValue = board[xpos][y_verify];
    if (verifyValue == value){
      return false;
    }
  }

  int box_x = xpos / 3;
  int box_y = ypos / 3;

  for (int y_verify = box_y * 3; y_verify < box_y * 3 + 3; y_verify++){
    for (int x_verify = box_x * 3; x_verify < box_x * 3 + 3; x_verify++){
      if (x_verify == xpos && y_verify == ypos){
        continue;
      }

      int verifyValue = board[x_verify][y_verify];
      if (verifyValue == value){
        return false;
      }
    }
  }
  return true;
}

void SudokuPuzzle::printTracerTryingValue(int xpos, int ypos){
  if(debug){
    for (int i = 0; i < xpos+ypos; i++){
      cout << " ";
    }
    cout << "Trying value " << board[xpos][ypos] << " at board[" << xpos << "][" \
<< ypos <<"]" << endl;
  }
}

int main(int argc, char *const argv[]){
  SudokuPuzzle puzzle;
  string filename;
  string line;
  ifstream in;
  ofstream out;

  cout << "Enter filename:" << endl;
  cin >> filename;
  in.open(filename);
  while(getline(in, line)){
    puzzle.line.print()
  }
  cout << endl;

  if(puzzle.solve()){
    cout << "Solution:" << endl;
    puzzle.print();
  }
  else{
    cout << "Puzzle is not solvable.";
  }
  cout << endl;
  return 0;
}

最佳答案

你的问题写得有点困惑,但我会尽量按照我的理解来回答它。首先,我希望您的文本文件中没有实际的函数调用——没有办法像从文本文件中那样直接调用函数。 另外,在你的 while main() 中的声明, 调用 puzzle.line.print()没有意义,因为 print()不是 std::string 的方法并且您的“线”不是 SudokuPuzzle 类型的成员。

因此,如果您只对存储和读取您希望输入有规律的网格上的位置感兴趣,您可能有一个看起来像这样的文件:

0 0 1
1 1 3
2 2 9
...(etc)

从那里开始,在不考虑输入或错误检查的情况下,我们可能有一些像这样的代码来从文件中读取:

std::ifstream readFile("Text.txt"); //construct ifstream object from text file
std::vector<int> vec;
int file_input; //temporary variable to hold input
while(readFile >> file_input)
{
  vec.push_back(file_input);
};
readFile.close();

使用文件流就像使用 std::cinstd::cout ;您使用流运算符 <<>>在流和其他数据之间传输信息。

现在,我们可以对数据结构进行任何需要的处理(在本例中为 std::vector,但它可以是任何东西)。

当我们需要写回去的时候,可以使用这样的代码:

std::ofstream writeFile("Text.txt"); //overwrites contents!
for(unsigned i = 0; i < vec.size(); ++i)
{
  //this is just to format the text output to the same way it came in
  writeFile << vec[i] << ' ';
  if ((i + 1) % 3 == 0)
    writeFile << '\n';
}
writeFile.close();

在格式化输出文本的代码块中,您可能想要做一些事情,比如使用 | 这样的字符。和 _创建一些网格模式。您应该对如何去做有所了解(想想它们需要插入的位置,它们应该出现在可预测的位置)。

Here's some example code as well.

关于c++ - 输入/输出文件(数独求解器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39177198/

相关文章:

c++ - 如何将整个 Visual c++ 项目加载到 Enterprise Architect 中以对其进行逆向工程?

c++ - 具有由整数模板参数指定的参数数量的类方法

c++ - 默认情况下是默认构造函数/赋值 noexcept/constexpr 吗?

php - 如何从对象的数组记录集中获取嵌套的 HTML 列表?

c++ - 递归函数扫描字符串添加ASCII

c++ - 是否存在加载多个 mscvrt**.dll 版本的问题?

c++ - 如何实现以下C++输出格式?

c++ - 在 C++ 中以十六进制读取文件

java - 树打印树方法

c++ - 在到达 main() 函数之前,通过所有嵌套函数重新抛出异常是一种好习惯吗?