某编程大赛中设计有一个挑战环节,选手可以查看其他选手的代码,发现错误后,提交一组测试数据将对手挑落马下。为了减小被挑战的几率,有些选手会故意将代码写得很难看懂,比如把所有回车去掉,提交所有内容都在一行的程序,令挑战者望而生畏。
为了对付这种选手,现请你编写一个代码排版程序,将写成一行的程序重新排版。当然要写一个完美的排版程序可太难了,这里只简单地要求处理C语言里的for、while、if-else这三种特殊结构,而将其他所有句子都当成顺序执行的语句处理。输出的要求如下:
- 默认程序起始没有缩进;每一级缩进是 2 个空格;
- 每行开头除了规定的缩进空格外,不输出多余的空格;
- 顺序执行的程序体是以分号“;”结尾的,遇到分号就换行;
- 在一对大括号“{”和“}”中的程序体输出时,两端的大括号单独占一行,内部程序体每行加一级缩进,即:
1 2 3 |
{ 程序体 } |
- for的格式为:
1 2 3 |
for (条件) { 程序体 } |
- while的格式为:
1 2 3 |
while (条件) { 程序体 } |
- if-else的格式为:
1 2 3 4 5 6 |
if (条件) { 程序体 } else { 程序体 } |
输入格式:
输入在一行中给出不超过 331 个字符的非空字符串,以回车结束。题目保证输入的是一个语法正确、可以正常编译运行的 main 函数模块。
输出格式:
按题面要求的格式,输出排版后的程序。
输入样例:
1 |
int main() {int n, i; scanf("%d", &n);if( n>0)n++;else if (n<0) n--; else while(n<10)n++; for(i=0; i<n; i++ ){ printf("n=%d\n", n);}return 0; } |
输出样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
int main() { int n, i; scanf("%d", &n); if ( n>0) { n++; } else { if (n<0) { n--; } else { while (n<10) { n++; } } } for (i=0; i<n; i++ ) { printf("n=%d\n", n); } return 0; } |
分析:point表示当前处理的文本位置,space储存但前需要在行首加多少空格,mark表示自动补充的大括号数量,use表示是否开启了大括号自动补充。在Function函数内,集成了’跳过无效空格’、’空格输出’、’关键字匹配’以及’补充的打括号补全’功能,很好用。刚开始我们需要将int main ()部分单独输出,因为该部分可能存在不可移出的空格。然后对于剩下的主体部分,主要分成三个模块处理——’大括号匹配整理’、’关键字匹配整理’以及’其余代码匹配整理’。特别注意在有些关键字后面添加了代码没有自带大括号,需要自己去补全并记录相关数量信息。在space为0时结束程序,剩下的就是简单的模拟即可~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
#include <bits/stdc++.h> using namespace std; int point, space = 2, mark, tp, cnt, use, temp; string s; int Function(int c) { if (c == 0) while (s[point] == ' ') point++; else if (c == 1) for (int i = 0; i < space; i++) cout << ' '; else if (c == 2) { if (s.substr(point, 2) == "if" && (s[point + 2] == '(' || s[point + 2] == ' ')) return 2; else if (s.substr(point, 3) == "for" && (s[point + 3] == '(' || s[point + 3] == ' ')) return 3; else if (s.substr(point, 4) == "else" && (s[point + 4] == '(' || s[point + 4] == ' ')) return 4; else if (s.substr(point, 5) == "while" && (s[point + 5] == '(' || s[point + 5] == ' ')) return 5; } else if (c == 3) { Function(0); if (Function(2) == 4) return 0; while (mark) { space -= 2; Function(1); cout << "}\n"; mark--; } } return 0; } int main() { getline(cin, s); Function(0); for (int i = point; s[i] != ')'; i++) cout << s[i]; cout << ")\n{\n"; point = s.find('{') + 1; while (1) { Function(0); temp = Function(2); if (s[point] == '{') { Function(1); cout << "{\n"; space += 2; point++; } else if (s[point] == '}') { space -= 2; Function(1); cout << "}\n"; if (space == 0) return 0; Function(3); point++; } else if (temp) { Function(1); cout << s.substr(point, temp); point += temp; if (temp != 4) { Function(0); tp = point; cnt = 0; while(tp < s.size()) { if (s[tp] == '(') cnt++; else if (s[tp] == ')') cnt--; tp++; if (cnt == 0) break; } cout << ' ' << s.substr(point, tp - point); point = tp; } cout << " {\n"; space += 2; Function(0); if (s[point] != '{') { use = 1; mark++; } else { use = 0; point++; } } else { Function(1); cnt = s.find(';', point); cout << s.substr(point, cnt - point + 1) << '\n'; point = cnt + 1; if (use && mark) { space -= 2; Function(1); cout << "}\n"; mark--; Function(3); } } } return 0; } |
❤ 点击这里 -> 订阅《PAT | 蓝桥 | LeetCode学习路径 & 刷题经验》by 柳婼