人工智能homework1_____c++ 回溯法解决数据(以命令行形式读入txt,输出在txt)

回溯法简单讲就是循环+递归,教材是从八皇后问题开始讲。

一开始对递归理解不深,这个数独作业写了几天。递归有点数学中的数列,有a(n+1)=f(a(n));得出相邻两步关系。最重要的要加上递归结束条件。而退出递归的过程,函数也是一层一层退出!


再讲讲用回溯解答数独(要求每行,每列,每个小九宫格的数字不同),

for(char num='1';num<='9';num++){     //这就是开始所说的循环

       检查当前格子是否符合要求 ,符合就填写下一个格子  //这就是开始说的递归过程

       }



附近中是我读取的txt

具体c++代码;


Sudoku.h头文件

#ifndef SUDOKU_H
#define SUDOKU_H


#include<iostream>
#include<fstream>
#include <string>


using namespace std;


class Sudoku{
private:
char element[9][9];
char save[9][9]; //保存数独结果,用于写入txt
bool isValid(const int &row=0,const int &column=0); //判断当前格子里数字是否合格
void backtrace(int row=0,int column=0); //回溯核心算法
public:
Sudoku();
void input(const string &fileName); //读取txt成员函数
void solve(); //解答数独,并输出控制台成员函数
void output(const string &fileName);//写入txt成员函数
};


#endif // !SUDOKU_H

------------------------------------------------------------------

Sudoku.cpp源文件

/**********回溯法**********/

#include "Sudoku.h"

Sudoku::Sudoku(){
	for(int i=0;i<9;i++)
		for(int j=0;j<9;j++){
			element[i][j]='0';
			save[i][j]='0';
		}
}

bool Sudoku::isValid(const int &row,const int &column){
	for(int j=0;j<9;j++) //  检验行是否符合条件
		if(element[row][j]==element[row][column]&&j!=column)
			return false;
	for(int i=0;i<9;i++) //检查列是否符合
		if(element[i][column]==element[row][column]&&i!=row)
			return false;
	for(int i=row/3*3;i<row/3*3+3;i++)  //检测小的九宫格是否符合
		for(int j=column/3*3;j<column/3*3+3;j++)
			if(element[i][j]==element[row][column]&&i!=row&&j!=column)
				return false;
	return true;
}

void Sudoku::backtrace(int row,int column){  //回溯法核心代码
	if(row>8){  //最后一层递归结束,并打印结果
		cout<<"The result:"<<endl;
		for(int i=0;i<9;i++){
			for(int j=0;j<9;j++){
				save[i][j]=element[i][j];
				cout<<save[i][j];
			}
			cout<<endl;
		}
		return;
	} 

	for(;row<9;row++){    //找出'0',即代表未知格子
		for(;column<9;column++)
			if(element[row][column]=='0')
				break;
		if(column==9)
			column=0;
		if(element[row][column]=='0')
			break;
	}
	for(char num='1';num<='9';num++){ //逐个尝试
		element[row][column]=num;
		if(isValid(row,column)){
			if(column<8)
				backtrace(row,column+1); //递归
			else if(row<9)
				backtrace(row+1,0);//递归
		}
	}
	element[row][column]='0'; //当前层次不符合条件是,置'0'回溯
}

void Sudoku::solve(){
	backtrace(0,0);
}

void Sudoku::input(const string &fileName){
	ifstream fin;
	string line;
	fin.open(fileName.c_str());
	if(!fin){  //判断文件是否正常打开
		cout<<"Unable to open the file!"<<endl;
		exit(1);
	}
	int i=0;
	while(getline(fin,line)){ //逐行读取输入流中的文件,直至该输入流结束
		for(int j=0;j<9;j++)
			element[i][j]=line[j]; //提取字符串中的每个字符
		i++;
	}
	fin.close();  //关闭文件
	cout<<"The input:"<<endl;  //输出原始数据到控制台
	for(int i=0;i<9;i++){
		for(int j=0;j<9;j++)
			cout<<element[i][j];
		cout<<endl;
	}	
}

void Sudoku::output(const string &fileName){
	ofstream fout(fileName.c_str());
	if(!fout){
		cout<<"error!"<<endl;
		exit(1);
	}
	for(int i=0;i<9;i++){
		for(int j=0;j<9;j++)
			fout<<save[i][j];  //逐个写入输出文件
		fout<<endl;
	}
	fout.close();

}




--------------------------------------------------------------------------------------------------------------------------------------------

main.cpp

#include "Sudoku.h"

void main(int argc,char *argv[]){
	Sudoku mySudoKu;
	if(argc!=3){
		cout<<"please input the program,the address of input txt and address of output txt like this:"<<endl;
		cout<<"        "<<"Sudoku.exe  ***.txt(for input)   ***.txt(for output)"<<endl;
		exit(1);		
	}
	mySudoKu.input(argv[1]);
	//mySudoKu.input("G:\\研究生一年级\\人工智能\\作业\\149409758_1_homework1\\homework1\\test1.txt");
	mySudoKu.solve();
	//mySudoKu.output("G:\\研究生一年级\\人工智能\\作业\\149409758_1_homework1\\homework1\\output.txt");
	mySudoKu.output(argv[2]);
	//getchar();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值