C++ 竞赛入门
index
对拍
1. 背景
做题目的时候,如果这个题目的只有样例通过,或只拿到部分的时候,我们需要一个数据,这个数据可以过标程或暴力但不能过过我们的代码,以此来找到我们代码中错误
2. 基础知识
diff命令的使用
diff命令的是linux自带的命令,它可以比较两个文本文件的不同
首先创建两个文件1.txt,2.txt,内容如下
对比
1
2
3
4
5
1
2
2
4
5
[[ctrl]] + [[alt]] + [[t]],打开termial,输入下面的内容
diff 1.txt 2.txt
那么这个输出格式是什么意思呢
得到结果
3c3
< 3
---
> 2
c表示change,3c3表示1.txt的第3行和2.txt的第3行对比,有改变
具体解释见 diff命令输出格式解读_车子 chezi的博客-CSDN博客_diff 输出
你再尝试一下其它命令
# q -> quiet,安静模式,相同,什么也不输出
diff -q 1.txt 1.txt
# q -> quiet,安静模式,不相同,输出指明不同
diff -q 1.txt 2.txt
# y -> side by slide,并排输出
diff -y 1.txt 2.txt
# 指定宽度为30
diff -W 30 -y 1.txt 2.txt
# 只输出不同的行
diff --suppress-common-lines -y 1.txt 2.txt
终极杀招vimdiff
vimdiff 1.txt 2.txt
vimdiff具有下面的优点
- 命令简单
- 显示完美
- 相同的行会折叠
- 不相同的行会高亮
3. diff 返回的值
我们知道,我们写的c++代表的main函数都会return一个整数,同样diff命令在运行结束 后也会返回一个值. 那么怎么得到这个值呢?
diff 1.txt 1.txt
echo $?
会输出0,表示diff的两个文件一样
4. diff 命令的与||的拼接
diff -q 1.txt 1.txt || echo "yes"
我们知道 在c++,里||是逻辑或运行符号,那么这里是什么意思呢?
比较反直觉的是bash是如何判断一个程序运行的是否正确,如下
- 一个命令运行的返回值是0,bash认为是true,这个程序运行正确
- 一个命令运行的返回值是非0,bash认为是false,这个程序运行不正确
||的运算规则和c++里一样,A || B
试一试下面的命令
# 不会输出yes
true || echo "yes"
# 会输出yes
false || echo "yes"
- 如果A是true,不会执行B,因为整体
A || B一定是true - 如果A是false,会执行B
The right side of && will only be evaluated if the exit status of the left side is zero (i.e. true). || is the opposite: it will evaluate the right side only if the left side exit status is non-zero (i.e. false).
结论 只有diff执行失败时才会执行,echo yes
5. 创建 shell 对拍脚本
可以编写 shell 脚本依次运行数据生成程序、标准程序和待测程序,再用 diff
比较输出。将脚本保存为 dp.sh 后,赋予执行权限:
chmod +x dp.sh
./dp.sh
如果希望在任意目录使用脚本,可以将它放入 PATH 中的个人脚本目录,并为不同的
程序名称设计命令行参数。
6 c++对拍程序
Q:因为我不熟悉bash脚本的编写,
,我比赛时无法记住上面的脚本,怎么办呢?
A:使用如下的c++代码
#include <iostream>
using namespace std;
int main(){
for(int i=1;i<=1000;++i){
cout << i << "\n";
// system 相当于手动执行一条命令
system("./rand > rand.out");
system("./my < rand.out > my.out");
system("./right < rand.out > right.out");
if( system("diff -q my.out right.out") != 0){
cout << "error \n";
return 1;
}
}
cout << "all right\n";
return 0;
}