problem
L3-019 代码排版 (30分) 某编程大赛中设计有一个挑战环节,选手可以查看其他选手的代码,发现错误后,提交一组测试数据将对手挑落马下。为了减小被挑战的几率,有些选手会故意将代码写得很难看懂,比如把所有回车去掉,提交所有内容都在一行的程序,令挑战者望而生畏。
为了对付这种选手,现请你编写一个代码排版程序,将写成一行的程序重新排版。当然要写一个完美的排版程序可太难了,这里只简单地要求处理C语言里的for、while、if-else这三种特殊结构,而将其他所有句子都当成顺序执行的语句处理。输出的要求如下:
默认程序起始没有缩进;每一级缩进是 2 个空格; 每行开头除了规定的缩进空格外,不输出多余的空格; 顺序执行的程序体是以分号“;”结尾的,遇到分号就换行; 在一对大括号“{”和“}”中的程序体输出时,两端的大括号单独占一行,内部程序体每行加一级缩进,即: { 程序体 } for的格式为: for (条件) { 程序体 } while的格式为: while (条件) { 程序体 } if-else的格式为: if (条件) { 程序体 } else { 程序体 } 输入格式: 输入在一行中给出不超过 331 个字符的非空字符串,以回车结束。题目保证输入的是一个语法正确、可以正常编译运行的 main 函数模块。
输出格式: 按题面要求的格式,输出排版后的程序。
输入样例: 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; } 输出样例: 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; }
给出一行代码,要求排版成整篇缩进2空格,花括号不换行,每行封号结尾
solution
去掉main单独输出(括号内可能有空格,WA1),剩下的按照每行的内容可以简单分为3类,遇到花括号(增加或减少缩进),逻辑判断(for,while,if+()一类,else一类),普通语句(以封号;结尾)。处理逻辑判断的时候有2个坑点,第一个坑点是考虑条件()内可能也有(),第二个是单句前后要加上花括号。其他的缩进修改和普通语句都比较简单直接处理就可。
#include<bits/stdc++.h>
using namespace std
;
int judge(string dat
, int i
){
if(dat
.find("if", i
)==i
&& (dat
[i
+2]==' '||dat
[i
+2]=='('))return 2;
if(dat
.find("for",i
)==i
&& (dat
[i
+3]==' ' ||dat
[i
+3]=='('))return 3;
if(dat
.find("while",i
)==i
&& (dat
[i
+5]==' '||dat
[i
+5]=='('))return 5;
if(dat
.find("else",i
)==i
&& dat
[i
+4]==' ')return 4;
return 0;
}
void erase_space(string dat
,int &i
){while(dat
[i
]==' ')i
++;}
void print_space(int sp
){for(int i
=0;i
<sp
;i
++)putchar(' ');}
int main(){
string dat
; getline(cin
,dat
);
int l
= dat
.find('i',0), r
= dat
.find(')',0);
cout
<<dat
.substr(l
,r
-l
+1)<<"\n{\n";
int tmp
, space
= 2;
int flag
, debt
=0;
for(int i
= dat
.find('{')+1,j
=0,k
; i
< dat
.size(); ){
erase_space(dat
,i
);
if(dat
[i
]=='{' || dat
[i
]=='}'){
if(dat
[i
]=='{'){
print_space(space
);
printf("{\n");
space
+= 2;
i
++;
continue;
}else{
space
-= 2;
print_space(space
);
printf("}\n");
i
++;
if(space
==0)break;
erase_space(dat
,i
);
while(debt
&& judge(dat
,i
)!=4){
space
-= 2;
print_space(space
);
printf("}\n");
debt
--;
}
}
}else if((tmp
=judge(dat
,i
))){
print_space(space
);
if(tmp
==4){
printf("else");
k
= i
+3;
}else{
cout
<<dat
.substr(i
,tmp
)<<" ";
i
+= tmp
;
erase_space(dat
, i
);
k
= i
; int t
= 0;
while(1){
if(dat
[k
]=='(')t
++;
if(dat
[k
]==')')t
--;
if(!t
)break;
k
++;
}
cout
<<dat
.substr(i
,k
-i
+1);
}
int m
= k
+1;
erase_space(dat
,m
);
if(dat
[m
] != '{'){
printf(" {\n");
flag
= 1;
debt
++;
i
= m
;
}else{
printf(" {\n");
flag
= 0;
i
= m
+1;
}
space
+= 2;
}else{
int ed
= dat
.find(';', i
);
print_space(space
);
cout
<<dat
.substr(i
,ed
-i
+1)<<"\n";
i
= ed
+1;
if(flag
&& debt
){
space
-= 2;
print_space(space
);
printf("}\n");
debt
--;
erase_space(dat
,i
);
while(debt
&& judge(dat
,i
)!=4){
space
-= 2;
print_space(space
);
printf("}\n");
debt
--;
}
}
}
}
return 0;
}