【CCCC】L3-019 代码排版 (30分),大模拟

it2026-04-20  5

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){ //WA3:当前位置是if并且不是在字符串内 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 main() 找i和)输出 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;//main的}输完就结束了 //【重复】单句特判 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); //处理for,while,if,+()或者else if(tmp==4){ printf("else"); k = i+3; }else{ cout<<dat.substr(i,tmp)<<" "; i += tmp; erase_space(dat, i); //考虑if()中也有()条件的情况 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; }
最新回复(0)