一般在做题时,会被一些数据卡住,除了边界数据外,很多数据是随机生成的,为了适配普遍情况的随机数据。
但是在线评测系统(OJ)一般不公开测试数据,这是一个OJ 的命脉。
做题的时候,时常会很难造出来一些数据,这时候,就可以随机生成数据,再用一个已知正确的做法去对比答案(如果有std,则可以采用std,否则可以自己写一个暴力的做法,暴力虽然不能通过题目,但是可以帮助我们debug)。
下面是一个对拍程序的几个部分:
- 数据生成器:
gen
- 需要debug的代码
my.cpp
- 已知正确的代码
std.cpp
- 运行程序并对比答案的脚本
check.sh
题目
求解 $A \times B$ ,其中 A 和 B 都是 $32$ 位有符号整数。
my.cpp
1
2
3
4
5
6
7
8
9
10
|
#include <iostream>
int main()
{
int a, b;
std::cin >> a >> b;
std::cout << a * b << std::endl;
return 0;
}
|
std.cpp
1
2
3
4
5
6
7
8
9
10
|
#include <iostream>
int main()
{
long long a, b;
std::cin >> a >> b;
std::cout << a * b << std::endl;
return 0;
}
|
gen
1
2
3
4
5
6
|
#!/usr/bin/python3
import random
a = random.randint(-2**31, 2**31-1)
b = random.randint(-2**31, 2**31-1)
print(a, b)
|
check.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/bin/bash
g++ -std=c++11 std.cpp -o std
g++ -std=c++11 my.cpp -o my
for((i=1;i<=100;i++))
do
./gen > gen.in
./std < gen.in > std.out # 计算正确答案
./my < gen.in > my.out # 计算待测试算法的输出结果
if diff -w std.out my.out > /dev/null; then
echo "Test $i: AC"
else
echo "Test $i: WA"
exit 0
fi
done
echo "All tests passed"
|
写好后,运行 check.sh
。
运行多次,结果如下:
可以发现几乎都是在 Test1
就发现了错误的数据,这得益于这道题的数据很好溢出。
一般来说,如果一次执行不成功,可以尝试多次,如果多次都不成功,可能问题不在于普通数据上,需要考虑边界数据了。
发现错误后
发现了 WA 后,去当前路径下的 gen.in
中得到数据,并进行 debug 。一般来说,数据不要太大,否则不好 debug 。