【每日一题】PTA - L3-019 代码排版
2023-06-29 18:23:29 174浏览
PTA - L3-019 代码排版
题目
解题思路
- 大分天下,逐个治之
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String code = scanner.nextLine();
scanner.close();
code = indentCode(code);
System.out.println(code);
}
private interface Code {
default String spaceFitCount(int count) {
if (count == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
while (count-- > 0) {
sb.append(' ');
}
return sb.toString();
}
}
private static class CodeBlock implements Code {
// contains code blocks and code lines
List<Code> codes = new ArrayList<>();
// header code block start with the $spaceCount count of space
int spaceCount;
// code block 's header line, no over with the char of "{"
String codeHeader;
// parent
CodeBlock parent;
public CodeBlock(CodeBlock parent, String codeHeader) {
this.parent = parent;
if (parent != null) {
this.spaceCount = parent.spaceCount + 2;
} else {
this.spaceCount = 0;
}
this.codeHeader = codeHeader;
}
public void addCode(Code code) {
this.codes.add(code);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
String spaceStr = spaceFitCount(spaceCount);
if (parent == null) {
sb.append(codeHeader).append("\r\n").append("{\r\n");
} else {
sb.append(spaceStr).append(codeHeader).append(" {\r\n");
}
for (Code code : codes) {
sb.append(code.toString());
}
sb.append(spaceStr).append("}\r\n");
return sb.toString();
}
}
private static class CodeLine implements Code {
// code line parent
CodeBlock parent;
String strCodeLine;
int spaceCount;
public CodeLine(CodeBlock parent, String strCodeLine) {
this.parent = parent;
this.strCodeLine = strCodeLine;
this.spaceCount = parent.spaceCount + 2;
}
@Override
public String toString() {
return spaceFitCount(spaceCount) + strCodeLine + "\r\n";
}
}
private static String indentCode(String code) {
Matcher matcher = Pattern.compile("int\\s+main\\s*\\(\\s*\\)").matcher(code);
String formatCode = "";
if (matcher.find()) {
String strMain = matcher.group();
// main code block
matcher = Pattern.compile("\\{.*}").matcher(code);
if (matcher.find()) {
String strMainCodeBlack = matcher.group();
strMainCodeBlack = strMainCodeBlack.substring(1, strMainCodeBlack.length() - 1);
CodeBlock mainCodeBlock = new CodeBlock(null, strMain);
parseCodeBlack(strMainCodeBlack, mainCodeBlock);
formatCode = mainCodeBlock.toString();
}
}
return formatCode;
}
/**
* parse strCodeBlack into codeBlock
*/
private static void parseCodeBlack(String strCodeBlack, CodeBlock codeBlock) {
String local = parseWhile(strCodeBlack, codeBlock);
if (!strCodeBlack.equals(local)) {
parseCodeBlack(local, codeBlock);
return;
}
local = parseFor(strCodeBlack, codeBlock);
if (!strCodeBlack.equals(local)) {
parseCodeBlack(local, codeBlock);
return;
}
local = parseIf(strCodeBlack, codeBlock);
if (!strCodeBlack.equals(local)) {
parseCodeBlack(local, codeBlock);
return;
}
local = parseUsual(strCodeBlack, codeBlock);
if (!strCodeBlack.equals(local)) {
parseCodeBlack(local, codeBlock);
}
}
private static final Pattern scanfPat = Pattern.compile("^\\s*scanf\\(\\s*?\".*?\"\\s*?,.*?\\);");
private static final Pattern printfPat = Pattern.compile("^\\s*printf\\(\\s*?\".*?\"\\s*?,.*?\\);");
private static final Pattern varPat = Pattern.compile("^.*?;");
private static String parseUsual(String strCodeBlack, CodeBlock codeBlock) {
Matcher matcher = scanfPat.matcher(strCodeBlack);
if (!matcher.find()) { // scanf("xxx", d, a);
matcher = printfPat.matcher(strCodeBlack);
if (!matcher.find()) {
// variable define;
matcher = varPat.matcher(strCodeBlack);
if (!matcher.find()) {
return strCodeBlack;
}
}
}
int end = matcher.end();
String strCodeLine = strCodeBlack.substring(0, end).trim();
codeBlock.addCode(new CodeLine(codeBlock, strCodeLine));
strCodeBlack = strCodeBlack.substring(end);
return strCodeBlack;
}
private static final Pattern ifPat = Pattern.compile("^\\s*if\\s*\\(?");
private static String parseIf(String strCodeBlack, CodeBlock codeBlock) {
// if ( (a == b) && ( a == 'c' ) ) {
Matcher matcher = ifPat.matcher(strCodeBlack);
if (matcher.find()) { // if(
// strCodeBlack = " if ( (a == b) && ( a == 'c' ) ) ";
Object[] objects = doParseCondition(strCodeBlack, codeBlock);
strCodeBlack = (String) objects[0];
codeBlock = (CodeBlock) objects[1]; // if
matcher = bracketPat.matcher(strCodeBlack);
if (matcher.find()) { // if (...) { : has '{'
int start = matcher.end();
int count = 0, end = start;
for (int i = 0; i < strCodeBlack.length(); i++) {
char ch = strCodeBlack.charAt(i);
if (ch == '{') {
count++;
continue;
}
if (ch == '}') {
count--;
if (count == 0) {
end = i;
break;
}
}
}
end++;
parseCodeBlack(strCodeBlack.substring(start, end - 1), codeBlock);
strCodeBlack = strCodeBlack.substring(end);
strCodeBlack = parseElse(strCodeBlack, codeBlock.parent);
return strCodeBlack;
}
// if (...)
strCodeBlack = parseSingle(strCodeBlack, codeBlock);
strCodeBlack = parseElse(strCodeBlack, codeBlock.parent);
return strCodeBlack;
}
return strCodeBlack;
}
private static final Pattern elsePat = Pattern.compile("^\\s*else");
private static String parseElse(String strCodeBlack, CodeBlock codeBlock) {
Matcher matcher = elsePat.matcher(strCodeBlack);
if (!matcher.find()) {
return strCodeBlack;
}
CodeBlock elseCodeBlack = new CodeBlock(codeBlock, "else");
codeBlock.addCode(elseCodeBlack);
codeBlock = elseCodeBlack;
strCodeBlack = strCodeBlack.substring(matcher.end());
matcher = bracketPat.matcher(strCodeBlack);
if (matcher.find()) { // else { : has '{'
int start = matcher.end();
int count = 0, end = start;
for (int i = 0; i < strCodeBlack.length(); i++) {
char ch = strCodeBlack.charAt(i);
if (ch == '{') {
count++;
continue;
}
if (ch == '}') {
count--;
if (count == 0) {
end = i;
break;
}
}
}
end++;
parseCodeBlack(strCodeBlack.substring(start, end - 1), codeBlock);
return strCodeBlack.substring(end);
}
// else
strCodeBlack = parseSingle(strCodeBlack, codeBlock);
return strCodeBlack;
}
private static final Pattern whilePat = Pattern.compile("^\\s*while\\s*\\(?");
private static String parseWhile(String strCodeBlack, CodeBlock codeBlock) {
Matcher matcher = whilePat.matcher(strCodeBlack);
return doParseWhileAndFor(matcher, strCodeBlack, codeBlock);
}
private static final Pattern bracketPat = Pattern.compile("^\\s*\\{");
private static String doParseWhileAndFor(Matcher matcher, String strCodeBlack, CodeBlock codeBlock) {
if (!matcher.find()) { // while/for(
return strCodeBlack;
}
Object[] objects = doParseCondition(strCodeBlack, codeBlock);
strCodeBlack = (String) objects[0];
codeBlock = (CodeBlock) objects[1];
matcher = bracketPat.matcher(strCodeBlack);
if (matcher.find()) { // while/for (...) { : has '{'
int start = matcher.end();
int count = 0, end = start;
for (int i = 0; i < strCodeBlack.length(); i++) {
char ch = strCodeBlack.charAt(i);
if (ch == '{') {
count++;
continue;
}
if (ch == '}') {
count--;
if (count == 0) {
end = i;
break;
}
}
}
end++;
parseCodeBlack(strCodeBlack.substring(start, end - 1), codeBlock);
return strCodeBlack.substring(end);
}
// while/for ()
strCodeBlack = parseSingle(strCodeBlack, codeBlock);
return strCodeBlack;
}
private static final Pattern forPat = Pattern.compile("^\\s*for\\s*\\(?");
private static String parseFor(String strCodeBlack, CodeBlock codeBlock) {
Matcher matcher = forPat.matcher(strCodeBlack);
return doParseWhileAndFor(matcher, strCodeBlack, codeBlock);
}
private static String parseSingle(String strCodeBlack, CodeBlock codeBlock) {
String tmpStrCodeBlack = parseWhile(strCodeBlack, codeBlock);
if (!tmpStrCodeBlack.equals(strCodeBlack)) {
return tmpStrCodeBlack;
}
tmpStrCodeBlack = parseFor(strCodeBlack, codeBlock);
if (!tmpStrCodeBlack.equals(strCodeBlack)) {
return tmpStrCodeBlack;
}
tmpStrCodeBlack = parseIf(strCodeBlack, codeBlock);
if (!tmpStrCodeBlack.equals(strCodeBlack)) {
return tmpStrCodeBlack;
}
tmpStrCodeBlack = parseUsual(strCodeBlack, codeBlock);
return tmpStrCodeBlack;
}
private static Object[] doParseCondition(String strCodeBlack, CodeBlock codeBlock) {
int end = 0, count = 0;
for (int i = 0; i < strCodeBlack.length(); i++) {
char ch = strCodeBlack.charAt(i);
if (ch == '(') {
count++;
continue;
}
if (ch == ')') {
count--;
if (count == 0) {
end = i;
break;
}
}
}
end++;
String strCodeLine = strCodeBlack.substring(0, end).trim();
// System.out.println(strCodeLine);
CodeBlock conditionCodeBlock = new CodeBlock(codeBlock, strCodeLine);
codeBlock.addCode(conditionCodeBlock);
strCodeBlack = strCodeBlack.substring(end);
return new Object[]{strCodeBlack, conditionCodeBlock};
}
}
优化
无
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
暂无评论,快来写一下吧
展开评论



