当前位置: 首页 > news >正文

同样算法的DFS求解数独C和Python程序用时比较

在网上看到一个特别简短的DFS求解数独C程序,
我把输入改成一个字符串。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
bool hang[10][10],lie[10][10],fz[10][10];//做记录
//例如 hang[1][2]=1,代表第一行有数字2
//     lie[3][4]=1,代表第3列有数字4
//     fz[1][5]=1,代表方针1有数字5
int sd[10][10];//代表数独的元素
// 输出
void print1() {for(int i=1;i<=9;i++) {for(int j=1;j<=9;j++) {cout<<sd[i][j]<<" ";}cout<<endl;}//system("pause");exit(0);
}
//做记录
void record(int x,int y) {hang[x][sd[x][y]]=1;lie[y][sd[x][y]]=1;fz[(x-1)/3*3+(y-1)/3+1][sd[x][y]]=1;
}
//销毁记录
void derecord(int x,int y) {hang[x][sd[x][y]]=0;lie[y][sd[x][y]]=0;fz[(x-1)/3*3+(y-1)/3+1][sd[x][y]]=0;sd[x][y]=0;
}
void dfs(int x,int y) {//当这个数原本就有if(sd[x][y]!=0) {//当搜到(9,9)时候,全部已经弄完,就输出结果if(x==9 && y==9) print1();//当搜到(x,9)时,说明这一行已经搜完了,该搜下一行了else if(y==9) dfs(x+1,1);//以上都不满足就搜这行的下一个数else dfs(x,y+1);}//当这个数原本没有else {//循环遍历,依次输入1-9,一次一次试。for(int i=1;i<=9;i++) {//如果这行,列,方阵都没有i这个数,就可以假设它是iif((!hang[x][i]) && (!lie[y][i]) && (!fz[(x-1)/3*3+(y-1)/3+1][i])) {//先假设是isd[x][y]=i;// 做记录record(x,y);//当搜到(9,9)时候,全部已经弄完,就输出结果if(x==9 && y==9) print1();//当搜到(x,9)时,说明这一行已经搜完了,该搜下一行了else if(y==9) dfs(x+1,1);//以上都不满足就搜这行的下一个数else dfs(x,y+1);//下一个格子1-9都找不到,说明假设不成立,就销毁已经做了的记录,就假设是下一个数derecord(x,y);}}//1-9都假设完了,发现还不满足,说明上一个格子假设有问题,返回上一个格子return;}
}
int main() {char s[82]="";cin>>s;for(int i=1;i<=9;i++) {for(int j=1;j<=9;j++) {sd[i][j]=s[(i-1)*9+j-1]-'0';// 不是0就做记录if(sd[i][j]) {record(i,j);}}}dfs(1,1);cout<<"该数独无解"<<endl;//system("pause");return 0;
}

让DeepSeek改写成Python,

import sys
import timeclass SudokuSolver:def __init__(self):self.r = [[False] * 10 for _ in range(10)]  # 行记录self.c = [[False] * 10 for _ in range(10)]  # 列记录self.g = [[False] * 10 for _ in range(10)]  # 宫记录self.sd = [[0] * 10 for _ in range(10)]     # 数独数组def print_sudoku(self):"""输出数独结果"""for i in range(1, 10):for j in range(1, 10):print(self.sd[i][j], end=" ")print()print()def record(self, x, y):"""做记录"""num = self.sd[x][y]self.r[x][num] = Trueself.c[y][num] = Trueg_index = (x - 1) // 3 * 3 + (y - 1) // 3 + 1self.g[g_index][num] = Truedef derecord(self, x, y):"""销毁记录"""num = self.sd[x][y]self.r[x][num] = Falseself.c[y][num] = Falseg_index = (x - 1) // 3 * 3 + (y - 1) // 3 + 1self.g[g_index][num] = Falseself.sd[x][y] = 0def dfs(self, x, y):"""深度优先搜索求解"""# 当这个数原本就有if self.sd[x][y] != 0:# 当搜到(9,9)时候,全部已经弄完,就输出结果if x == 9 and y == 9:self.print_sudoku()return True# 当搜到(x,9)时,说明这一行已经搜完了,该搜下一行了elif y == 9:return self.dfs(x + 1, 1)# 以上都不满足就搜这行的下一个数else:return self.dfs(x, y + 1)# 当这个数原本没有else:# 循环遍历,依次输入1-9,一次一次试for i in range(1, 10):g_index = (x - 1) // 3 * 3 + (y - 1) // 3 + 1# 如果这行,列,方阵都没有i这个数,就可以假设它是iif not self.r[x][i] and not self.c[y][i] and not self.g[g_index][i]:# 先假设是iself.sd[x][y] = i# 做记录self.record(x, y)result = False# 当搜到(9,9)时候,全部已经弄完,就输出结果if x == 9 and y == 9:self.print_sudoku()result = True# 当搜到(x,9)时,说明这一行已经搜完了,该搜下一行了elif y == 9:result = self.dfs(x + 1, 1)# 以上都不满足就搜这行的下一个数else:result = self.dfs(x, y + 1)# 如果找到解,直接返回if result:return True# 下一个格子1-9都找不到,说明假设不成立,就销毁已经做了的记录,就假设是下一个数self.derecord(x, y)# 1-9都假设完了,发现还不满足,说明上一个格子假设有问题,返回上一个格子return Falsedef solve(self, puzzle_str):"""解数独主函数"""# 重置所有记录self.r = [[False] * 10 for _ in range(10)]self.c = [[False] * 10 for _ in range(10)]self.g = [[False] * 10 for _ in range(10)]self.sd = [[0] * 10 for _ in range(10)]# 将字符串转换为数独数组index = 0for i in range(1, 10):for j in range(1, 10):if index < len(puzzle_str):char = puzzle_str[index]if char.isdigit() and char != '0':self.sd[i][j] = int(char)self.record(i, j)else:self.sd[i][j] = 0index += 1# 开始求解return self.dfs(1, 1)def solve_sudoku_print(puzzle_str):"""求解数独并打印结果"""solver = SudokuSolver()if not solver.solve(puzzle_str):print("该数独无解")def main():if len(sys.argv) != 2:print("用法: python script.py <文件名>")b='000000068900000002000400500041000000000035000050000000000800010300000700000100400';solve_sudoku_print(b)returnfilename = sys.argv[1]try:with open(filename, 'r', encoding='utf-8') as file:while True:line = file.readline().strip()if line == '':breakprint(f"题目: {line}")t = time.time()solve_sudoku_print(line)print(f"耗时: {round(time.time()-t, 4)} s")print("-" * 50)except FileNotFoundError:print(f"错误: 文件 '{filename}' 不存在")except Exception as e:print(f"错误: {e}")if __name__ == "__main__":main()

用selen求解器程序提供的最难级别例子测试,结果如下:

g++ backsudo.cpp -O3 -o back
time echo "000000000000003085001020000000507000004000100090000000500000073002010000000040009" | ./back
9 8 7 6 5 4 3 2 1 
2 4 6 1 7 3 9 8 5 
3 5 1 9 2 8 7 4 6 
1 2 8 5 3 7 6 9 4 
6 3 4 8 9 2 1 5 7 
7 9 5 4 6 1 8 3 2 
5 1 9 2 8 6 4 7 3 
4 7 2 3 1 9 5 6 8 
8 6 3 7 4 5 2 1 9 real	0m1.743s
user	0m1.740s
sys	0m0.000spython3 pyback.txt selensudo.txt
题目: 000000000000003085001020000000507000004000100090000000500000073002010000000040009
9 8 7 6 5 4 3 2 1 
2 4 6 1 7 3 9 8 5 
3 5 1 9 2 8 7 4 6 
1 2 8 5 3 7 6 9 4 
6 3 4 8 9 2 1 5 7 
7 9 5 4 6 1 8 3 2 
5 1 9 2 8 6 4 7 3 
4 7 2 3 1 9 5 6 8 
8 6 3 7 4 5 2 1 9 耗时: 173.0466 spypy3/bin/pypy3 pyback.txt selensudo.txt
题目: 000000000000003085001020000000507000004000100090000000500000073002010000000040009
9 8 7 6 5 4 3 2 1 
2 4 6 1 7 3 9 8 5 
3 5 1 9 2 8 7 4 6 
1 2 8 5 3 7 6 9 4 
6 3 4 8 9 2 1 5 7 
7 9 5 4 6 1 8 3 2 
5 1 9 2 8 6 4 7 3 
4 7 2 3 1 9 5 6 8 
8 6 3 7 4 5 2 1 9 耗时: 32.0108 s
--------------------------------------------------

比较结果可见,用时差100倍,改用pypy执行python程序,快了5倍。

http://www.dtcms.com/a/610299.html

相关文章:

  • vue3+element-china-area-data 实现省市区三级联动
  • Next.js 项目常见报错排查与解决
  • Vue 校验输入时间与当前时间差大于等于3小时
  • html中网站最下面怎么做设计主题网站
  • 起重机智能选型:从血泪教训到科技护航的革新之路
  • java+maven配置yguard的一次实验
  • 汝南县网站建设Wordpress实现中英文
  • ASC学习笔记0006:游戏效果将如何复制到客户端
  • 延安市住建建设网站无锡网站营销推广
  • 我想做网站服务器选用什么电子商务网站建设总结与体会
  • Oracle分页sql
  • Airsim仿真、无人机、无人车、Lidar、深度强化学习
  • Airsim仿真、无人机、Lidar深度相机、DDPG深度强化学习
  • 做做网站下载2023常熟网站网站建设
  • app推广策略WordPress优化百度广告
  • pinctrl子系统介绍
  • python-MCPServer拉取和使用部署
  • 17.TCP编程(二)和序列化
  • x^3 - 3x + 1 = 0
  • Nacos 9848启动端口占用 Failed to bind to address 0.0.0.0/0.0.0.0:9848
  • 前端react 开发 图书列表分页
  • 做vip视频网站赚钱吗最近一周新闻大事件
  • 大数据安全技术实验:Hadoop环境部署
  • 【07】特征匹配算法:ORB算法深度解析与实现
  • vite7更新了哪些内容
  • Aemulo2.0门禁卡复制卡片后修改设置卡片备注名称
  • IP应用场景全图谱:你的IP属于哪一类?
  • 微网站开发 在线商城一键部署wordpress
  • Rust实战:使用Clap和Tokio构建现代CLI应用
  • 中移建设有限公司网站猎头可以做单的网站