8皇后问题的c++与python实现对比

本文通过解决经典的八皇后问题,比较了C++与Python两种语言的特点。使用Python简洁优雅地实现了问题求解,并进一步用C++进行了实现与性能对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c++经典书多,但貌似不太新,而python则新书很多,能体现一些新思路新概念。看python的书,写python代码,再用c++实现一遍,这样互补的学习方式貌似也蛮适合自己的。
在《Beginning Python From Novice to Professional》一书的八皇后问题上,python果然精妙而优雅。
在对待
  1. foreachpossibilityatlevel1:
  2. foreachpossibilityatlevel2:
  3. foreachpossibilityatleveln:
  4. ...
  5. isitviable
形式的循环下,它有yield, generator递归。短短20来行代码就搞定了八皇后,如下:
  1. defconflict(state,nextX):
  2. nextY=len(state)
  3. ifnextY==0:print0
  4. foriinrange(nextY):
  5. ifabs(nextX-state[i])in(0,nextY-i):
  6. returnTrue
  7. returnFalse
  8. defqueen(num,state=()):
  9. printstate
  10. forposinrange(num):
  11. ifnotconflict(state,pos):
  12. iflen(state)==num-1:
  13. yield(pos,)
  14. else:
  15. forresultinqueen(num,state+(pos,)):
  16. yield(pos,)+result
  17. defprettyprint(solution):
  18. defline(pos,length=len(solution)):
  19. return'.'*pos+'X'+'.'*(length-pos-1)
  20. forposinsolution:
  21. printline(pos)
  22. if__name__=='__main__':
  23. importrandom
  24. prettyprint(random.choice(list(queen(4))))
其中
  1. forresultinqueen(num,state+(pos,)):
  2. yield(pos,)+result
2句由为精妙,自己苦思很久,没有能完全理解yield的精髓。。。。。

在用c++实现的时候,一直想模仿实现这句话的功能,却被这句话困扰了2个多小时,看书看久了不休息果然效率奇差。
今天早上醒来,才恍然大悟,其实不就是个栈么。
  1. /*
  2. *=====================================================================================
  3. *
  4. *Filename:eightqueen.cpp
  5. *
  6. *Description:8皇后问题,c++实现
  7. *
  8. *Version:1.0
  9. *Created:2008年12月30日19时46分52秒
  10. *Revision:none
  11. *Compiler:gcc
  12. *
  13. *Author:LiWeiJian(mn),lwj1396@163.com
  14. *Company:hunanuniversity
  15. *
  16. *=====================================================================================
  17. */
  18. #include<vector>
  19. #include<iostream>
  20. #include<cmath>
  21. usingnamespacestd;
  22. boolconflict(constvector<int>&state,intnextX)
  23. {
  24. intnextY=state.size();
  25. for(inti=0;i<nextY;i++)
  26. {
  27. if(abs(nextX-state[i])==0||abs(nextX-state[i])==(nextY-i))
  28. returntrue;
  29. }
  30. returnfalse;
  31. }
  32. voidqueen(intnum,vector<int>&state)
  33. {
  34. for(inti=0;i<num;i++)
  35. {
  36. state.clear();
  37. state.push_back(i);
  38. intpos=0;
  39. while(state.size()!=num)
  40. {
  41. if(conflict(state,pos))//冲突了
  42. {
  43. if(pos==num-1)//已经是最后一个位置
  44. {
  45. state.pop_back();
  46. break;
  47. }
  48. pos++;//尝试下一个pos
  49. continue;
  50. }
  51. else//没有冲突
  52. {
  53. state.push_back(pos);
  54. pos=0;
  55. }
  56. }
  57. if(state.size()==num)
  58. return;
  59. }
  60. }
  61. voidprint(intnum,constvector<int>result)
  62. {
  63. for(inti=0;i<result.size();i++)
  64. {
  65. for(intj=0;j<result[i];j++)
  66. cout<<".";
  67. cout<<"X";
  68. for(intj=0;j<num-result[i]-1;j++)
  69. cout<<".";
  70. cout<<endl;
  71. }
  72. }
  73. intmain()
  74. {
  75. vector<int>state;
  76. queen(16,state);
  77. print(16,state);
  78. }

在实现之后,对比了一下,效率的差距果然满大,python跑14皇后,等了几分钟没搞定,而c++跑16皇后,都是刷的一下出来了,不过可能c++没有用递归也是一个原因。

最后再总结2句:
1 一本书,无论薄厚,都不能欺负它,不要想1,2天就看完
2 c++虽然经典,但书籍过老了,要拿一门有活力的语言为它开路,其实boost的c++已经很python了。

<think>好的,用户想了解N皇后问题的定义和相关背景,以及算法实现。首先,我需要整理N皇后问题的基本定义,确保准确无误。根据引用[1]和[3],N皇后问题是在N×N棋盘上放置N个皇后,使得它们互不攻击。需要解释清楚攻击的条件:同一行、列或对角线。 接下来是背景部分,可能需要提到这个问题起源于19世纪,由国际象棋玩家提出,后来成为计算机科学中的经典回溯算法例子。引用[2]和[3]提到回溯算法,这里需要强调回溯在其中的作用,以及为什么这个问题适合用回溯解决。 然后是算法实现部分。用户之前的对话中已经讨论过C++的递归回溯实现,现在需要简明扼要地概述实现步骤,可能参考引用[4]和[5]提到的初始化棋盘、逐行放置、冲突检测、回溯等步骤。同时要提到不同的优化方法,比如位运算或对称剪枝,如引用[3]和用户之前的回答中提到的。 用户可能还想知道不同算法的时间复杂度,这里需要比较基本回溯和优化后的版本,如用户之前提供的表格。还要注意是否需要代码示例,用户之前的示例是C++,但引用[2]有Python实现,可能需要提及多种语言的实现,但根据用户当前的问题,可能更关注概念而非具体代码。 另外,用户可能对应用场景感兴趣,可以提到N皇后问题在算法教学、测试和组合优化中的重要性,如引用[2]和[3]所述。最后,确保回答结构清晰,分点说明,并生成相关问题,如优化方法、其他算法对比等,参考用户之前的示例。</think>### N皇后问题定义及背景 #### 一、基本定义 N皇后问题是经典的组合优化问题,要求在$N \times N$的棋盘上放置$N$个皇后,使得它们**两两不互相攻击**。具体约束条件为: - 任意两个皇后不在同一行 - 任意两个皇后不在同一列 - 任意两个皇后不在同一对角线(包括主对角线和次对角线) 例如当$N=4$时,合法解可表示为: ``` . Q . . . . . Q Q . . . . . Q . ``` #### 二、历史背景 1. **起源**:1848年由国际象棋玩家Max Bezzel首次提出 2. **数学突破**:1874年高斯证明当$N>3$时至少存在一个解 3. **计算机领域**:1960年代成为测试回溯算法性能的基准问题[^1][^3] 4. **NP完全性**:1972年被证明属于NP完全问题,图着色等问题等价 #### 三、算法实现框架 ##### 标准回溯算法步骤 ```cpp void backtrack(int row) { if(row == n) { // 终止条件 记录解; return; } for(当前行所有列位置col) { if(安全检测通过) { 放置皇后; backtrack(row+1); // 递归下一行 移除皇后; // 回溯 } } } ``` ##### 关键组件解析 | 组件 | 功能说明 | 时间复杂度 | |----------------|-----------------------------------|------------| | 冲突检测 | 检查列/对角线冲突 | $O(n)$ | | 递归树深度 | 总行数n | - | | 每层分支因子 | 当前行可用列数 | $O(n)$ | | 总时间复杂度 | 理论$O(n^n)$,实际$O(n!)$[^3][^5] | - | #### 四、算法优化方向 1. **位运算加速** ```cpp // 使用三个位掩码记录列、左对角线、右对角线状态 void backtrack(int row, int cols, int ld, int rd) { if(row == n) count++; int pos = ~(cols | ld | rd) & ((1<<n)-1); // 获取可用位置 while(pos) { int p = pos & -pos; // 取最低有效位 backtrack(row+1, cols|p, (ld|p)<<1, (rd|p)>>1); pos &= pos-1; // 移除已选位置 } } ``` - 时间复杂度优化到$O(n!)$ - 空间复杂度降为$O(1)$[^5] 2. **对称性剪枝** - 利用棋盘的8种对称性(旋转/镜像) - 第一行仅需尝试前$\lceil n/2 \rceil$列 - 计算量减少约50%[^3] 3. **并行计算** ```python from concurrent.futures import ThreadPoolExecutor def parallel_solve(n): with ThreadPool
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值