ACM中如何对拍?
前言
记录一下我的学习过程,给自己点回忆,如果小伙伴不想看可以直接跳至后面代码段。
对拍,我也是才学的,之前打acm有用过,但都是队友敲对拍,我就专职撸代码。前几天朋友问我一个PAT的题目,我写了一会儿ac了,他用链表去做的,但就是没ac,我帮着debug了一下。因为我平时不常用链表,我也花了一定时间去读懂他的代码,分析他的逻辑以及增删是否有错误,这些大约花了我两三小时去做,但是还是没有找到bug。我想到了之前打ACM时候做的对拍,因为我有自己的AC代码,可以通过对拍去比较两份代码得到结果的不同,就去学习了一下对拍。
正文
多的不说了,上代码(附注释讲解):
#include <cstdio>
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
int t=10;//你想要测试的数据组数
while(t)
{
t--;
//所有程序不需要使用文件读写,就正常程序即可
//制造数据,就是自己编个程序,利用随机数产生满足题意的数据即可。
system("makedata.exe > data.txt");
//这里的b.exe为AC代码(或者暴力一定对的代码)生成的可执行文件
system("b.exe < data.txt > b.txt"); //调用b.exe输入为data.txt的内容 输出结果至b.txt
//这里的c.exe为待测试代码生成的可执行文件
system("c.exe < data.txt > c.txt"); //调用b.exe输入为data.txt的内容 输出结果至b.txt
//FC 一个DOS命令用于比较两个或两套文件,并显示不同处。
if(system("fc b.txt c.txt")) //比较b.txt和c.txt的差距
break;
}
if(t==0) cout<<"no error"<<endl;
else cout<<"error"<<endl;
getchar();//防止一出现错误,窗口就关闭了
return 0;
}
最后直接执行这个对拍程序编译生成的.exe可执行文件即可。
如何同时让一份代码跑多组数据
前言
这个是我在一个课程实验上遇到了,老师给了很多个测试文件比如test1.txt-test5.txt,对应要生成out1.txt-out5.txt。这个时候我就想起来了才学的对拍,就可以用上呀。
正文
首先按照我的想法,就是把system(“b.exe < data.txt > b.txt”)中见的字符串给替换成"b.exe < testi.txt > outi.txt"就行了嘛。代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <sstream>
#include <windows.h>
using namespace std;
//tostring 就是我自己写的一个把整数转换为字符串的函数
string tostring(int x)
{
string res="";
while(x!=0)
{
res+=char('0'+x%10);
x/=10;
}
int ls=res.length();
for(int i=0;i<ls/2;i++)
{
int oth=ls-1-i;
swap(res[i],res[oth]);
}
return res;
}
int main()
{
string inpre = "test";
string txt = ".txt";
string rk = " > ";
string outpre = "tokenOut";
for (int i = 1; i <= 7; i++)
{
string str = "a.exe < ";
str += inpre + tostring(i) + txt + rk;
str += outpre + tostring(i) + txt;
//const char *s=&str[0]; 上下两份代码的差异处
system(s); //输入data.txt 输出b.txt
//cout << str << endl;
}
return 0;
}
这样就相当于用个for循环去改变每一次的执行的dos命令里的文件名即可。
但是当我编译的时候却发现程序报错了,大致错误原因是system()的形参要求是const char *,而我的str就是一个字符串变量,那么必然会报错的呀?
解决方法
声明一个const char * s的指针,让其指向我的str就好了呀。
但是这里要注意,const char * s是不能通过s指针去修改值的,这也是这个const 的作用。所以每一次要通过str自己去修改就好了。
附可使用代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <sstream>
#include <windows.h>
using namespace std;
string tostring(int x)
{
string res="";
while(x!=0)
{
res+=char('0'+x%10);
x/=10;
}
int ls=res.length();
for(int i=0;i<ls/2;i++)
{
int oth=ls-1-i;
swap(res[i],res[oth]);
}
return res;
}
int main()
{
//system("a.exe < test1.txt > tokenOut1.txt");
string inpre = "test";
string txt = ".txt";
string rk = " > ";
string outpre = "tokenOut";
for (int i = 1; i <= 7; i++)
{
string str = "a.exe < ";
str += inpre + tostring(i) + txt + rk;
str += outpre + tostring(i) + txt;
const char *s=&str[0];//上下两份代码唯一不同的地方
system(s); //输入data.txt 输出b.txt
cout << str << endl;
}
return 0;
}
用上面的代码就可以一份代码跑多组数据,不用每次更改文件输入输出的路径那么麻烦了。
当然如果有小伙伴有更好的办法,也可以在评论区教教我啊!
欢迎评论和指正!