引言
算法调试常比编写更耗时,尤其是动态规划、递归等逻辑复杂的代码。本文分享一套系统化的调试方法,帮助快速定位问题。
一、调试前的准备
代码格式化
使用统一缩进(4 空格)和命名规范,避免因格式混乱导致的逻辑误读。边界条件枚举
提前列出测试用例:空输入、n=1、n = 最大值等极端情况。
二、动态规划调试技巧
打印 DP 表
对区间 DP,输出dp[i][j]
的中间结果,检查是否符合预期:// 调试时添加 for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cout << dp[i][j] << "\t";}cout << endl; }
验证子问题
以石子合并为例,先手动计算 n=3 的情况,对比程序输出是否一致。三、递归调试技巧
添加日志输出
记录递归参数和返回值,追踪调用路径:int dfs(int step, int l, int r) {cout << "call dfs(" << step << "," << l << "," << r << ")" << endl;// ... 逻辑 ...int res = ...;cout << "return " << res << endl;return res; }
- 限制递归深度
防止栈溢出,在调试时添加深度判断:if (step > 1000) {cerr << "可能栈溢出" << endl;exit(1); }
四、常见 BUG 类型与对策
数组越界
使用assert(i >= 0 && i < n)
在关键位置添加断言。初始化错误
对 DP 数组,确保初始值正确(如dp_min
初始化为inf
,dp_max
初始化为 0)。循环边界错误
用小数据测试循环变量范围,如i < n
还是i <= n
。- GDB 调试器:设置断点、单步执行、查看变量
- Visual Studio Code:集成调试功能,支持变量监视
- Online Judge:提交前用 OJ 的测试用例验证