L3-1 代码排版(Java)
分数 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; }
答案
import java.util.Scanner; public class CodeFormatting { static int ignoreSpace(String s, int d, int t) { while (d < s.length() && d > 0 && s.charAt(d) == ' ') { d += t; } return d; } static int trimSpace(StringBuilder s, int d, int t) { if (s.charAt(d) != ' ') { s.insert(d, " "); } d += t; int i = 0; while (i + d < s.length() && s.charAt(i + d) == ' ') { i++; } if (i > 0) { s.delete(d, d + i); } return d; } static boolean judge(String s, int d, int[] flag) { if (d > 0 && Character.isLetter(s.charAt(d - 1))) { return false; } if (s.substring(d, d + 2).equals("if") && (s.charAt(d + 2) == ' ' || s.charAt(d + 2) == '(')) { return true; } if (s.substring(d, d + 3).equals("for") && (s.charAt(d + 3) == ' ' || s.charAt(d + 3) == '(')) { return true; } if (s.substring(d, d + 5).equals("while") && (s.charAt(d + 5) == ' ' || s.charAt(d + 5) == '(')) { return true; } flag[0] = 0; if (s.substring(d, d + 4).equals("else") && (s.charAt(d + 4) == ' ' || s.charAt(d + 4) == '{')) { return true; } return false; } static void perfect(StringBuilder s) { for (int i = s.length() - 1; i >= 0; i--) { int ise = 1; if (s.charAt(i) == ')') { int d = 1, j = i - 1; while (d > 0 && j >= 0) { if (s.charAt(j) == ')') { d++; } else if (s.charAt(j) == '(') { d--; } j--; } i = j + 1; } else if (judge(s.toString(), i, new int[]{ise})) { int j = i; while (j < s.length() && Character.isLetter(s.charAt(j))) { j++; } if (ise != 0) { j = trimSpace(s, j, 1); int d = 1; while (d != 0 && ++j < s.length()) { if (s.charAt(j) == '(') { d++; } else if (s.charAt(j) == ')') { d--; } } j++; } j = trimSpace(s, j, 1); if (s.charAt(j) != '{') { s.insert(j, "{"); j++; int flag = 0; while (j < s.length()) { if (s.charAt(j) == ';' && flag == 0) { s.insert(j + 1, "}"); break; } else if (s.charAt(j) == '(') { flag++; } else if (s.charAt(j) == ')') { flag--; } else if (s.substring(j, j + 2).equals("if")) { flag++; } else if (s.substring(j, j + 4).equals("else")) { flag--; if (flag == 1 && s.charAt(ignoreSpace(s.toString(), j + 1, 1)) != 'e') { flag--; } if (flag == 0) { s.insert(j + 1, "}"); break; } } else if (s.charAt(j) == '{') { flag++; } else if (s.charAt(j) == '}') { flag--; if (flag == 1 && s.charAt(ignoreSpace(s.toString(), j + 1, 1)) != 'e') { flag--; } if (flag == 0) { s.insert(j + 1, "}"); break; } } j++; } } } } } static void putSpace(int k) { while (k-- > 0) { System.out.print(" "); } } static boolean check(char s) { return s == ')' || s == 'e' || s == '{' || s == '}' || s == ';'; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int flag = 0, spaceNum = 0, start = 1; StringBuilder s = new StringBuilder(scanner.nextLine()); perfect(s); for (int i = ignoreSpace(s.toString(), 0, 1); i < s.length(); i++) { if (start == 1) { start = 0; if (s.charAt(i) == '}') { putSpace(spaceNum - 1); } else { putSpace(spaceNum); } } if (s.charAt(i) == '{') { int d = ignoreSpace(s.toString(), i - 1, -1); if (flag == 0 || !check(s.charAt(d))) { System.out.println(); putSpace(spaceNum); } flag = 1; System.out.print(s.charAt(i) + "\n"); spaceNum++; start = 1; i = ignoreSpace(s.toString(), i + 1, 1) - 1; } else if (s.charAt(i) == '}') { spaceNum--; System.out.print(s.charAt(i)); i = ignoreSpace(s.toString(), i + 1, 1) - 1; if (s.charAt(i + 1) == '}') { System.out.println(); start = 1; } else if (i < s.length() - 1) { System.out.println(); start = 1; } } else if (s.charAt(i) == '(') { int d = 1, j = i; System.out.print(s.charAt(i)); while (d > 0) { System.out.print(s.charAt(++j)); if (s.charAt(j) == '(') { d++; } else if (s.charAt(j) == ')') { d--; } } i = j; if (flag == 0) { i = ignoreSpace(s.toString(), i + 1, 1) - 1; } } else if (s.charAt(i) == ';') { System.out.print(s.charAt(i)); i = ignoreSpace(s.toString(), i + 1, 1) - 1; System.out.println(); start = 1; } else { System.out.print(s.charAt(i)); } } scanner.close(); } }