题目名称 | 3660. [统一省选 2022]预处理器 |
---|---|
输入输出 | preprocessor.in/out |
难度等级 | ★★☆ |
时间限制 | 1000 ms (1 s) |
内存限制 | 512 MiB |
测试数据 | 10 |
题目来源 | syzhaoss 于2022-04-16加入 |
开放分组 | 全部用户 |
提交状态 | |
分类标签 | |
分享题解 |
通过:3, 提交:3, 通过率:100% | ||||
SKG_G | 100 | 0.000 s | 0.00 MiB | C++ |
SKG_G | 100 | 0.000 s | 0.00 MiB | C++ |
guobinbin | 100 | 0.000 s | 0.00 MiB | C++ |
关于 预处理器 的近10条评论(全部评论) |
---|
宏是 C/C++ 语言的一项特性,它根据预先定义的规则进行文本替换(也被称为“宏展开”),能够实现定义常量、简化代码重复输入等功能。例如:
#define PI 3.14159 double area = PI * r * r;以上代码经过宏展开后变为:
double area = 3.14159 * r * r;
其中,宏定义命令变成了空行,而其他行中的宏被展开成了规则定义的文本。
C/C++ 语言代码在编译时对宏的处理由预处理器完成。你的任务是实现一个简化版的预处理器,要求如下:
以上两种预处理命令中,相邻两部分之间都严格用一个空格分隔。<name> 是由大小写字母和数字以及下划线组成的标识符(一个或多个字符),<content> 可以包含任意可打印 ASCII 字符(零个或多个字符)。一个宏定义的有效范围是从它定义所在行开始到后续最近的宏名匹配的取消定义所在行为止(如果没有对应的取消定义,则有效范围一直覆盖到文件结束)。
对普通文本进行宏展开时,将一行文本中每段连续极长的大小写字母和数字以及下划线视为标识符(而不是其中一部分),其余为其他字符。从左到右依次对文本中的标识符进行宏展开:
注意:出于简化的目的,本题的要求与 C/C++ 语言标准里的描述不完全一致,请以上面的要求为准。最明显的区别是本题只有标识符和其他字符两类词法单元,没有数
值、字符串、注释等。
输入的第一行包含一个正整数 $n$,表示要处理的代码行数。
接下来的 $n$ 行是要处理的代码。
输出 $n$ 行,为输入逐行预处理后的结果。
5 #define BEGIN { #define END } #define INTEGER int class C BEGIN INTEGER x; END; INTEGER main() BEGIN C c; END
class C { int x; }; int main() { C c; }
对 20% 的数据,不会出现宏定义命令 #define 和宏取消定义命令 #undef。
对另外 20% 的数据,不会出现多次展开的情况,且不会出现宏取消定义命令 #undef。
对另外 20% 的数据,不会出现多次展开的情况。
对另外 20% 的数据,不会出现递归展开的情况。
对其余数据,无特殊限制。
对 100% 的数据,$n\leq 100$,输入的每行字符数都不超过 100,且保证输出的每行字符数都不超过 1 000(字符数均不计行末换行符)。保证输入数据中的预处理命令都是合法的,包含但不限于:
也就是说,你不需要做任何语法和语义的错误检查。
本题进行输入时建议使用 C++ 语言的按行读入字符串功能,示例如下:
#include <iostream> #include <string> using namespace std; string line; // 从 cin 读入一行,放入 line 中(换行符被舍弃) getline(cin, line);
也可以使用 C 语言提供的 fgets 函数,示例如下:
#include <stdio.h> #define MAX_LEN 200 char line[MAX_LEN]; // 从 stdin 读入一行,放入 line 中(包含换行符) fgets(line, MAX_LEN, stdin);
注意:在读取行数 $n$ 之后可能需要额外读取一行以忽略其后的换行符。
2022 统一省选 Day1 Task1