CCF-201703-3-Markdown-(Java-100分)

这题图片很多就不贴图和复制题目了,直接进入正题
这题在第三题里面算是中等难度,但是我在练习时也花了很多时间,唉!这道题其实还是挺麻烦,很恶心的。

思路
一行行读取代码,遇到某行是空的,而且上一行是有代码的就表示此区块代码结束。我们要做的是在某个区块结束后输出某个区块的转换代码。

在读到区块首行的时候要判断是什么区块类型。是标题,列表还是段落?然后在区块代码blockCode中加入对应的头标签。结束的时候在区块代码blockCode里加对应的尾标签。

在读行的时候处理所有的链接和强调,处理完加入到区块代码blockCode中。

import java.util.Scanner;

public class Markdown {
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		String blockCode = "";
		String preLine = "";
		while (input.hasNextLine()) {
			String line = input.nextLine();
			//给此区间加头标签,当且仅当此行是区间首行且是非空行
			if (blockCode.length() == 0 && line.length() > 0) {
				if (line.charAt(0) == '#') {
					int hn = 0;
					for (int i = 0; i < line.length(); i++) {
						if (line.charAt(i) == '#')
							hn++;
						else
							break;
					}
					line = line.replaceFirst("#* *", "");
				}
				else if (line.charAt(0) == '*')
					blockCode += "
    \n"; else blockCode += "

    "; } //判断该行是否为列表 if (line.contains("*")) line = "

  • " + line.replaceFirst("\\* *", "") + "
  • "; //处理每行里面的行内标签 line = transToEm(line); line = transToLink(line); //识别到区间分割,给此区间加尾标签,然后输出 //当此行为空且前面行有内容,说明区间在此行开始分隔 if (preLine.length() > 0 && line.length() == 0) { blockCode = addLast(blockCode); System.out.println(blockCode); blockCode = ""; } //把非空行加入区间代码块中 if (line.length() > 0) blockCode += line + "\n"; preLine = line; } //最后一行因为没被识别到,要另外加尾标签然后输出 blockCode = addLast(blockCode); System.out.println(blockCode); } static String addLast(String blockCode) { //去掉代码块最后的换行符 blockCode = blockCode.substring(0, blockCode.length()-1); if (blockCode.contains(""; } else if (blockCode.contains("
      ")) blockCode += "\n
    "; else if (blockCode.contains("

    ")) blockCode += "

    "; return blockCode; } static String transToEm(String line) { while (line.contains("_")){ line = line.replaceFirst("_", ""); line = line.replaceFirst("_", ""); } return line; } static String transToLink(String line) { while (line.contains("[")) { String text = ""; String link = ""; int tIndexf = line.indexOf("["); int tIndexl = line.indexOf("]"); int lIndexf = line.indexOf("("); int lIndexl = line.indexOf(")"); text = line.substring(tIndexf + 1, tIndexl); link = line.substring(lIndexf + 1, lIndexl); line = line.replace(line.substring(tIndexf, lIndexl + 1), "" + text + ""); } return line; } }

新思路,先把代码读取成段落块,之后处理每个段落块,一行且开头是“#”的输出对应等级的标题标签和内容;开头是“*”的就是无序列表;剩余的就是段落。
行内标签用了正则表达式来替换。比之前的代码简洁了许多。注意一行会有多个行内标签,要区分开每个标签。

python代码:

import re

# em和a标签的正则表达式对象
em_obj = re.compile(r'_[^_]*_')
a_obj = re.compile(r'\[[^\[\]\(\)]*\]\([^\[\]\(\)]*\)')


# 替换em标签
def em_repl(match):
    return '{}'.format(match.group()[1:-1].strip())


# 替换a标签
def a_repl(match):
    s = match.group()
    idx1, idx2 = s.index(']'), s.index('(')
    cont, link = s[1:idx1], s[idx2 + 1:-1]
    return '{}'.format(link, cont)


codes = []  # 所有区块
part = []  # 一个区块

# 读取数据
try:
    while True:
        ip = input()
        if ip:
            part.append(ip)
        else:
            codes.append(part)
            part = []
except EOFError:
    pass
if part:
    codes.append(part)

# 确定行数的测试代码
# for i in range(19):
# ip = input()
# if ip:
# part.append(ip)
# elif part:
# codes.append(part)
# part = []
# if part:
# codes.append(part)

# 读取每个区块
for code in codes:
    # 标题
    if len(code) == 1 and code[0][0] == '#':
        h = code[0]
        i = h.count('#')
        content = h[i + 1:].strip()
        content = em_obj.sub(em_repl, content)
        content = a_obj.sub(a_repl, content)
        print('{}'.format(i, content, i))
    # 无序列表
    elif code[0][0] == '*':
        print('
    ') for e in code: content = e[2:].strip() content = em_obj.sub(em_repl, content) content = a_obj.sub(a_repl, content) print('
  • {}
  • '
    .format(content)) print('
'
) # 段落 else: print('

', end='') for j, e in enumerate(code): content = e.strip() content = em_obj.sub(em_repl, content) content = a_obj.sub(a_repl, content) print(content, end='') if j < len(code) - 1: print() print('

'
) # ### Hello # # # Hello, world! # # _ Hello, world! _ # # # a [hello](https://www.zhihu.com) . # a _[hello](https://www.zhihu.com)_ . # a [_hello_](https://www.zhihu.com) . # # # * 132 # * ewv # * 888ev # # _ 1181 _ _ erverver _ _ rerrrg _ # a [_hello_](https://www.zhihu.com) . --- [_hello_](https://www.zhihu.com) #

你可能感兴趣的:(CCF)