更好地修改bug——步骤可视化

这是我在csdn的第一篇文章,以后就在此记录代码生活orz(本人是新手)

太 长 不 看 版

根据显示步骤找错
问题
逻辑思考
写代码步骤可视化
遇到bug
方便问题解决

#强调#

  1. 一定要注意逻辑思考,别一上来就敲代码,脑子跟着bug出现跑,程序只为消除bug服务,最后通过测试,但你不清楚为啥是这样敲,耗时耗力收效甚微

  2. 可视化 :将重要步骤的最好在窗口中输出(如cout语句),方便debug,并且给你的代码添加注释,增加可读性

  3. 多测几个数字

意外收获:将除法化为乘法避免取整减少一些信息

以下是新版正文(2023.12.15更新)

代码题目要求:正确地找到字符串a和字符串b的公共子序列并输出结果,并输出最长子串长度。
测试输入:

123456789
234125679

错误代码如下

#include<iostream>
#include<cstring>
 using namespace std ;
int main (){
 	string a ;
 	string b ;
 	cin >> a >> b ;
 	int L1= b.size ();
 	int maxlen =0;
 	for (int i=0;i<L1;i++)
 	{
 		for ( int j=L1-1; j>i+1; j--){
    		if (( a.find(b.substr(i,j)))!=string::npos){
 				maxlen = max(j-i+1, maxlen); 
				cout<< b.substr(i,j)<< endl ;
			}
		}
	}
 	cout<<maxlen;
 	return 0;
 	}

如何修改呢?
1.加注释(弄清楚每一步干什么) 2.程序每一步执行可视化(添加cout语句)
以下为添加注释和cout语句的代码
cout语句的代码特地标黄

就可以很清楚的看到运行结果
非常方便找问题
分析问题:根据例子给出自己的答案与程序对照。
而我们自行判断出现234结果的情况是i=0,j=2;出现567的情况是i=5,j=7。但是可以看到与程序执行结果不同?哪里出现问题了?只能是strcat函数的理解!使用函数一定要知道各参数的含义
我们误以为是substr(i,j),是字符串从i到j,实际上,该函数要求从指定位置开始,并具有指定的长度。所以substr(i,j)的意思是从i开始,长度为j的字符串

以下是修改完成的代码(记得把辅助的cout语句注释掉噢~):

#include<iostream>
#include<cstring>
using namespace std;

int main() {
 string a;
 string b;
 cin >> a >> b;//读入字符串
 int L1 = b.size();//计算b的长度
 int maxlen = 0;//最长子串长度
 for (int i = 0; i < L1; i++) {
    //  cout<<"当i="<<i<<endl;
     for (int j = L1-i; j>=1; j--) {
        //   cout<<"当j="<<j<<",输出为"<<endl;
        //find函数在找不到指定值得情况下会返回string::npos,当不是string::npos的情况下执行
         if ((a.find(b.substr(i, j))) != string::npos) {
             maxlen = max(j, maxlen);//更新最长子串长度
             cout << b.substr(i, j) << endl;//输出相同子串
        	 }
     	}
 	}
 	cout << maxlen;//输出最长子串长度
 	return 0;
}

看看运行结果,nice!

标准输出:
234
23
2
34
3
4
12
1
2
567
56
5
67
6
7
9
3

以下是旧版正文(不用看)

以一道题为例谈谈最近的收获吧(虽然没有ac)
洛谷P1980在这里插入图片描述
以下是我的代码(有错误,不用看)

#include<iostream>
#include<cmath>
using namespace std;
int main() {
	int n,x,sum = 0;
	cin >> n >> x;
	for (int i = 1; i < n + 1; i++) {
		int j = 0;
		for (; j < 6; j++) {
			int a = i % 10;
			if (floor(i * 1.0 / (x * pow(10, j))) == 1) {
				++sum;
			}
		}
		if (i > 10) {
			int a = i % 10;
			if (a / x == 1) {
			sum++;
		}
	}
	}
	cout << sum;
	return 0;
}

你会发现你很难理解这代码是干嘛的,而且只有最后一个输出结果,debug无从下手,这时候可视化和注释的作用就发挥出来了,以下是新代码(修改过,还是不能ac)

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
int main() {
	
	int n, x, sum = 0;
	cin >> n >> x;
	//对n个数进行判断
	for (int i = 1; i <= n; i++) {
		//因为最大不超过10的6次方
		for (int j = 1; j <5 ; j++) {
			//只执行一次,判断个位数上时候存在x
			if (j == 1) {
				if ((i % 10) / x == 1) {
				//多添加的cout语句
					cout << "i=" << i << " 的个位数成立" <<  endl;
					sum++;
				}
				}
			
			//判断其余位数上是否有x
			if(j!=0) { 
				int a = n / (x * pow(10, j));
				if (a== 1) { 
				//多添加的cout语句
					cout << "i=" << i << "  10的" << j << "次方" << endl; 
					sum++; }
			}
		}
	}
	cout << sum;
	system("pause");
	return 0;
}

你会发现有些多添加的cout语句,让步骤可视化,还有一些注释,增强代码可读性
运行一下 发现非常清晰

多测试几个数字
如 12 2
出现bug了!把③也算进去了
审视我的代码
判断个位数时

if ((i % 10) / x == 1)
当i=3 x=2时 ,(3%10)/2 ,由于是整型运算,结果得到1,满足条件

修改方法 i%10==x

除法化为乘法避免取整减少一些信息

再测120 0发现bug了!!从111开始
这是因为我忘记考虑0的情况了 0的n次方都是0(n>0)
那我们就考虑10来代替0,再加代码

//判断其余位数上是否有x
			if (x != 0) {
				int a = i / (x * pow(10, j));
				if (a == 1) {
					cout << "i=" << i << "  10的" << j << "次方" << endl;
					sum++;
				}
			}
			else {
				int a = i /  pow(10, j);
				if (a!=0&&a %10== 0) {
					cout << "i=" << i << "  从右向左第" << j+1 << "位" << endl;
					sum++;
				}

再跑 : 520 1
跑出bug
可以看到411的十位上的1被忽略了
再改,再测,直到ac
注:以上代码并未通过题目
只是为了证明步骤可视化对修改bug的好处,希望大家能有所收获

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值