Input/Output 文件(数独求解器)
Input/Output file (Sudoku Solver)
首先,我是一名初学者编码员,我已经尝试处理和解决我的部分问题数小时但无法弄清楚。
除了两个任务,我已经完成了所有任务:
1.) 我不知道如何使用 ifstream 和 ofstream 的输入和输出文件机制来获取我的 .txt 文件来设置我的数独板的值。
2.) 我似乎无法弄清楚如何为单元格中每个 xyposition 的每个 "possible values" 打印一个数独板。
我正在尝试实现一个文本文件,内容如下:
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;
}
你的问题写得有点乱,我会尽量按照我的理解来回答的。首先,我希望您的文本文件中没有实际的函数调用——没有办法像从文本文件中那样直接调用函数。
此外,在 main()
中的 while
语句中,调用 puzzle.line.print()
没有意义,因为 print()
不是 std::string
的方法,而您的 'line' 不是 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::cin
或 std::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();
在设置输出文本格式的代码块中,您可能需要执行一些操作,例如使用 |
和 _
等字符来创建一些网格模式。您应该知道如何去做(想想它们需要插入的位置,它们应该出现在可预测的位置)。
首先,我是一名初学者编码员,我已经尝试处理和解决我的部分问题数小时但无法弄清楚。
除了两个任务,我已经完成了所有任务: 1.) 我不知道如何使用 ifstream 和 ofstream 的输入和输出文件机制来获取我的 .txt 文件来设置我的数独板的值。 2.) 我似乎无法弄清楚如何为单元格中每个 xyposition 的每个 "possible values" 打印一个数独板。
我正在尝试实现一个文本文件,内容如下:
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;
}
你的问题写得有点乱,我会尽量按照我的理解来回答的。首先,我希望您的文本文件中没有实际的函数调用——没有办法像从文本文件中那样直接调用函数。
此外,在 main()
中的 while
语句中,调用 puzzle.line.print()
没有意义,因为 print()
不是 std::string
的方法,而您的 'line' 不是 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::cin
或 std::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();
在设置输出文本格式的代码块中,您可能需要执行一些操作,例如使用 |
和 _
等字符来创建一些网格模式。您应该知道如何去做(想想它们需要插入的位置,它们应该出现在可预测的位置)。