- chjshen 的博客
命令行编译和对拍
- 2023-4-20 10:45:17 @
命令行编译
一.cmd的运行方式
- win+R 打开运行框,输入cmd回车,出现命令行窗口
- win 后在搜索中输入cmd回车,出现命令行窗口
- 在文件夹窗口的地址栏中输入cmd回车,出现命令行窗口。
在命令行中,常用到的命令如下表
内部命令 | 含义 | 参数 | 示例 |
---|---|---|---|
md | make directory | 新建立的文件夹名称 | md 123 |
rd | remove directory | 要删除的文件夹名称 | rd 123 |
cd | change directory | 要进入的文件夹名称 | cd 123 |
dir | 列出当前目录下的所有文件与文件夹 | ||
rename | 更改文件名 | 原文件名 新文件名 | rename 123.cpp 456.cpp |
del | 删除文件 |
另外:
- 使用E: 来改变盘
- 可以使用 echo somethings > 456.cpp 来直接生成一个456.cpp,内容是 somethings
- start 456.cpp 使用cpp关联的程序打开456.cpp
- notepad 1.in 使用记事本打开1.in
二.设置path
在命令行中运行命令时,系统查找此命令的方式可以理解为先在当前目录中查找,如果没有找到,再在环境变量path设置的路径中查找;如果显示找不到此命令时,可能是环境变量path中没有此命令的路径,可以在我的电脑上右键属性中找高级属性设置,找到系统环境变量中path,修改path,注意,新加的目录与之前的要用英文状态下的分号(;)进行分隔。修改完成后cmd窗口需要重新打开。
三.命令行编译
将g++的路径加入path后,重启命令行窗口后可以使用g++ -v来测试成功与否。
成功后,可以使用命令 g++ 你要编译的源代码文件名 -o 要生成的可执行文件名 来编译,如:
g++ 123.cpp -o 123
g++ 123.cpp -o 123 -O2 (2级优化,俗称吸氧)
g++ 123.cpp -o 123 -std=c++11 (使用c++11标准编译)
四、命令行重定向
- 命令 > 文件:将命令的输出重定向至文件中,会
覆盖原来所有内容
- 命令 < 文件 :将文件内容做为命令的输入
五、文件内容比较
fc 文件1 文件2
如果有不同,会输出有那些不同,没有不同,fc命令返回0
六、一个完整的命令行示例
g++ 1.cpp -o 1 && 1 < 1.in > 1.out && fc 1.ans 1.out /w
对拍
对拍是一种进行检验或调试的方法,通过对比两个程序的输出来检验程序的正确性。可以将自己程序的输出与其他程序的输出进行对比,从而判断自己的程序是否正确。
对拍过程要多次进行,因此需要通过批处理的方法来实现对拍的自动化。
具体而言,对拍需要一个数据生成器 和两个要进行输出结果比对的程序。
每运行一次数据生成器都将生成的数据写入输入文件,通过重定向的方法使两个程序读入数据,并将输出写入指定文件,最后利用 Windows 下的 fc
命令比对文件(Linux 下为 diff
命令)来检验程序的正确性。如果发现程序出错,可以直接利用刚刚生成的数据进行调试。
对拍的步骤
- 建立编写brust程序
- 建立编写opt程序
- 编写数据生成器程序
- 编写对拍程序并运行此程序进行对拍
brust程序(正确的程序或别人正确的程序)
644差分(模板)题目示例
/* created by chjshen, date: 2023-04-18 11:02 */
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1E5 + 5;
int n, m, a, b, s[N];
int l, r, t;
void handle()
{
for (int i = l; i <= r; i++)
{
if (t == 0)
s[i] -= b;
else
s[i] += a;
}
}
void initInput(void)
{
cin >> n >> m >> a >> b;
for (int i = 1; i <= n; i++) cin >> s[i];
for (int i = 1; i <= m; i++)
{
cin >> l >> r >> t;
handle();
}
for (int i = 1; i <= n; i++) cout << s[i] << " ";
cout << endl;
}
int main(void)
{
initInput();
return 0;
}
opt程序(优化后的程序或自己其他的程序)
644差分(模板)题目示例
/* created by chjshen, date: 2023-04-18 16:19 */
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1E5 + 5;
#define debug cout << "DEBUG" << endl
int n, m, a, b, s[N], d[N];
void handle(int l, int r, int c)
{
if (c == 0)
d[l] -= b, d[r + 1] += b;
else
d[l] += a, d[r + 1] -= a;
}
void show()
{
for (int i = 1; i <= n; i++)
{
d[i] = d[i - 1] + d[i];
cout << d[i] << " ";
}
cout << endl;
}
void initInput(void)
{
cin >> n >> m >> a >> b;
for (int i = 1; i <= n; i++)
{
cin >> s[i];
d[i] = s[i] - s[i - 1];
}
for (int i = 1; i <= m; i++)
{
int l, r, c;
cin >> l >> r >> c;
handle(l, r, c);
}
}
int main(void)
{
initInput();
show();
return 0;
}
数据生成器
- 最好是保证数据随机,可以生成大样例,但是在对拍时我们应该生成小样例数据,方便调试和查错。
- 如何生成随机数据:seed rand RAND_MAX ect.. 示例程序:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
int n, m;
int main(int argc, char * argv[])
{
int t = 10;
if(argc > 1)
{
t = atoi(argv[1]);
}
srand(time(0) + t);
n = rand() % 10 + 1; // 0 - RANDMAX
m = rand() % 5 + 1;
while(n <= m)
{
n = rand()% 10 +1;
}
cout << n << " " << m << endl;
int a[11];
for(int i = 1; i <= m; i++)
a[i] = i;
for(int i = m + 1; i <= n; i++)
{
a[i] = rand() % m + 1;
}
random_shuffle(a + 1, a + n + 1);
for(int i = 1; i <= n; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
对拍程序
- 程序化(脚本化)实现 数据生成器生成的随机 样例数据用a程序和b程序运行得结果a.out 和 b.out,自动对比是否相同。 示例程序:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int main()
{
// 1. 先编译3个文件 force.cpp, opt.cpp, data.cpp
system("g++ force.cpp -o force");
system("g++ opt.cpp -o opt");
system("g++ data.cpp -o data");
for(int i = 1; i <= 10000; i++)
{
// 2. 生成输入文件 pai.in
char f[200];
sprintf(f, "data %d > pai.in", i);
system(f);
// 1. 用force生成答案 pai.ans
system("force < pai.in > pai.ans");
// 2. 生成pai.out
system("opt < pai.in > pai.out");
// 3. 比较两个生成的文件
if(system("fc pai.ans pai.out >null"))
{
cout << i << ": WA!" << endl;
break;
}
else
cout << i << ": AC" << endl;
}
return 0;
}