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

用上面的代碼就可以一份代碼跑多組數據,不用每次更改文件輸入輸出的路徑那麼麻煩了。
當然如果有小夥伴有更好的辦法,也可以在評論區教教我啊!
歡迎評論和指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章