ACM中如何对拍?如何同时让一份代码跑多组数据?

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;
}

用上面的代码就可以一份代码跑多组数据,不用每次更改文件输入输出的路径那么麻烦了。
当然如果有小伙伴有更好的办法,也可以在评论区教教我啊!
欢迎评论和指正!

猜你喜欢

转载自blog.csdn.net/wjl_zyl_1314/article/details/105567389
今日推荐