【Code】代码答案错误怎么办?三种方法教你如何查错

在写完代码的时候,测一下样例,很多时候样例过了,但交到OJ上却挂了,始终找不到错误原因。有时候连样例都过不了。因此,我总结了三种方法教给大家,让大家有方向地去查错,而不是看着程序发呆。希望大家可以把三种方法熟练掌握,并懂得去运用。

1.目测法

目测法并不是简单的目测。
此方法用于数据小且少的题目。

用例子来说话:

FZU-1889 龟兔赛跑
原题 vjudge

这题其实很简单。

直接给代码。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define R                  register int
#define re(i,a,b)          for(R i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))

using namespace std;

typedef long long LL;

int main() {
    int X;
    scanf("%d",&X);
    while(X--) {
        int t,k,u,v;
        scanf("%d%d%d%d",&t,&k,&u,&v);
        int a=(t-k)*u;
        int b=t*v;
        if(a>b) printf("0\n");
            else if(a<b) printf("1\n");
                else printf("-1\n");
    }
    return 0;
}

这题固然简单,但万一你在测样例的时候错了。
目测法应该是比较好的方法。

那到底怎么目测呢?

1 首先你要找到一组使你程序错误的数据。

比如t=6,k=3,u=6,v=3

2 然后把你的大脑想象成电脑。

3一步一步执行程序中的语句。

读入:

scanf("%d%d%d%d",&t,&k,&u,&v);

计算:

int a=(t-k)*u;
int b=t*v;

把此时的计算结果牢牢记在脑子里。

判断输出:

if(a>b) printf("0\n");
	else if(a<b) printf("1\n");
		else printf("-1\n");

4 比较你的输出结果和标准输出结果是否相同。

这有点想NOIP初赛里的看程序写结果。

2.调试法

Dev-cpp这个软件自带调试功能,但我建议大家不要用。
我希望大家手动调试。
原因:
1 Linux环境下没有Dev-cpp这个软件
2 许多大神用的都是Linux,他们没有用这种调试功能
3 手动调试可以提高你对代码的熟悉程度和熟练程度
4 某些比赛不提供Dev-cpp这个软件
5 当程序复杂的时候,用自动调试很困难
6 用手动调试可以加快打字速度,以免在比赛的时候来不及

好,废话不说,直接开始讲。

其实很简单,就是在中途输出变量,判断变量的值是否正确。

完。

比如说很多初学者会犯这样的错误:

int main() {
    int i=0;
    int a[20];
    while(i++) {
        scanf("%d",&a[i]);
        if(i==10) break;
    }
    return 0;
}

运行一下发现没有读入。

你可以这样:

int main() {
    int i=0;
    int a[20];
    while(i++) {
        scanf("%d",&a[i]);
        cout << "###" << endl;
        if(i==10) break;
    }
    return 0;
}

这是看while()循环有没有执行
也可以这样:

int main() {
    int i=0;
    int a[20];
    while(i++) {
        scanf("%d",&a[i]);
        cout << a[i] << endl;
        if(i==10) break;
    }
    return 0;
}

看一下a[i]有没有被读入。

其实把i++改成++i就可以了。

注意:调试完了一定要删除调试的语句,或这样:

//cout << a[i] << endl;

不然很可惜,你就WA了。

3.对拍法(初谈)

对拍,又称“对答案”。
这种方法相对来讲就比较高级了。

在OI/ACM比赛中,这种方法是很常见的。

比如说我要检查一段高精度加法有没有写错。
对拍是最好不过的选择。
它比手动造数据强多了。
(C++高精度模板:点击这里

1 新建一个文件夹并打开

2 新建三个文件:my.cpp std.cpp make.cpp

make.cpp 用于自动制造数据
my.cpp 中放入你要检查的程序(高精度加法程序)
std.cpp 中放入标程(低精度加法程序)

//std.cpp
#include <iostream>
using namespace std;

int a,b;

int main() {
	cin >> a >> b;
	cout << a+b << endl;
	return 0;
}

3 打开make.cpp ,写造数据的程序

//make.cpp
#include<bits/stdc++.h>

using namespace std; 

int main() {
	srand(time(0)); 
	int a=rand()%1000+1;
	int b=rand()%1000+1;
	cout << a << endl << b << endl;
	return 0; 
}

下面开始解释:

srand(time(0)); 

上者是播放随机种子,为制造随机数埋下伏笔。

int a=rand()%1000+1;
int b=rand()%1000+1;

上着是产生随机数。
r a n d ( ) rand() rand() 可以产生 0 ~ 215-1 这个范围内的随机数。
r a n d ( ) rand() rand()%1000+1 就是产生1 ~ 1000 这个范围的随机数。

如果你想更数据更大,可以尝试这样写:

long long a=1LL*rand()*rand()*rand();
long long b=1LL*rand()*rand()*rand();
cout << a << endl << b << endl;

上者是输出 输入数据。

4 把std.cpp make.cpp my.cpp 编译,不需要运行

其目的是为了生成exe文件

5 新建一个文件 run.bat

6.右键run.bat 点击编辑,用记事本打开

千万不要双击打开

7.将下面这段话复制到run.bat中,保存,关闭

@echo off
:loop 
make > std.in
echo %time%
std < std.in > std.out
echo %time%
my  < std.in > my.out
echo %time%
fc std.out my.out
if errorlevel=1 pause 
goto loop

这段话的分析:

make > std.in

用make.exe制造输入文件std.in

echo %time%

输出时间t1,得到程序开始的时间

std < std.in > std.out

运行std.exe得到标准输出文件

echo %time%

输出时间t2, t 1 − t 2 t1-t2 t1t2就是std.exe运行所用的时间

my  < std.in > my.out

运行my.exe得到my.cpp的输出文件

echo %time%

输出时间t3, t 3 − t 2 t3-t2 t3t2就是my.exe运行的时间,这可以检查你的my.cpp是否超时

fc std.out my.out

比较std.oout和my.out是否相同,结果返回到errorlevel

if errorlevel=1 pause 

如果errorlevel=1(比较结果不相同),那么pause(暂停)

@echo off
:loop 

goto loop

无限循环

8.双击运行run.bat

在这里插入图片描述
如果一直找不到差异,那么它就不停地输出信息。

如果你的程序有错,就会出现这样的情况:
在这里插入图片描述
出现不同。
这个意思就是你的程序错了。

此时关闭run.bat

在文件夹中,你会找到std.in这个文件
这就是使你程序错的输入数据。

把你的程序改正之后,再次运行run.bat 看是否有错。

再谈:https://blog.csdn.net/Ljnoit/article/details/119640724

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值