02题解-洛谷 P2395 BBCode转换Markdown 题解
洛谷 P2395 BBCode转换Markdown 题解
题目传送门: here.
一道毒瘤的大模拟,给了你一部分的 BBCode 和 Markdown 语法,叫你转换。如下表:
BBCode | Markdown |
---|---|
[h1]文字[/h1] |
# 文字 # |
[h2]文字[/h2] |
## 文字 ## |
[i]文字[/i] |
*文字* |
[b]文字[/b] |
__文字__ |
[url=链接]文字[/url] |
[文字](链接) |
[img=地址]文字[/img] |
 |
[quote]文字[/quote] |
> 文字 |
如果标签没闭合输出Unclosed Mark
, 标签配合不对输出Match Error
。
虽然但是这代码一点也不像 Markdown 吧, >
不应该是区块标签嘛
有几个坑点:
- 临时用的变量一定要清空!特别是 string!
- 这里判断标签闭合和匹配可以使用栈
- 因为
url
和img
也可能嵌套,所以需要再开一个栈存储它们的地址。 [quote]
的判断比较特殊,里面的东西保持原样,所以如果遇到这个标签可以一次性读到[/quote]
闭合标签,或者EOF。- 最后就是细心了!这玩意我调了两天!
代码:(可能有点丑,见谅)
#include <iostream> #include <map> #include <string> #include <stack> using namespace std; enum OPER // 方便switch的东西 { NULOP, H1 = 1, // 一级标题 H2, // 二级标题 I, // 斜体 B, // 粗体 URL, // 链接 IMG, // 图片 QUOTE, // 代码段 _H1 = 11, // 一级标题 _H2, // 二级标题 _I, // 斜体 _B, // 粗体 _URL, // 链接 _IMG, // 图片 _QUOTE // 代码段 }; stack<OPER> sta; //用来存标签 stack<string> stac; // 用来存url、img的地址 map<string, OPER> mp; // 方便switch的东西 string s, t, op1, o; string tmp; char st; int Wrong = 1; // 2 Match Error 3 Unclos ed Mark void init()//对map映射的处理 { mp["h1"] = H1; mp["/h1"] = _H1; mp["h2"] = H2; mp["/h2"] = _H2; mp["/i"] = _I; mp["i"] = I; mp["/b"] = _B; mp["b"] = B; mp["/url"] = _URL; mp["url"] = URL; mp["/img"] = _IMG; mp["img"] = IMG; mp["/quote"] = _QUOTE; mp["quote"] = QUOTE; return; } int main() { // ios::sync_with_stdio(false); init(); st = getchar(); while (st != EOF){ if (st == '['){ op1.clear(); t.clear(); tmp.clear(); st = getchar(); for (int i = 0; st != ']'&&st!='='&&st!=EOF; i++){ op1.push_back(st); st = getchar(); } if (st == '='){ st = getchar(); while (st != ']'&&st!=EOF){ t.push_back(st); st = getchar(); } } switch (mp[op1]){ case H1: sta.push(H1); s += "# "; break; case _H1: if (!sta.empty() && sta.top() == H1){ s += " #"; sta.pop(); } else{ Wrong = 2; goto ERROR; } break; case H2: sta.push(H2); s += "## "; break; case _H2: if (!sta.empty() && sta.top() == H2){ s += " ##"; sta.pop(); } else{ Wrong = 2; goto ERROR; } break; case I: sta.push(I); s += "*"; break; case _I: if (!sta.empty() && sta.top() == I){ s += "*"; sta.pop(); } else{ Wrong = 2; goto ERROR; } break; case B: sta.push(B); s += "__"; break; case _B: if (!sta.empty() && sta.top() == B){ s += "__"; sta.pop(); } else{ Wrong = 2; goto ERROR; } break; case URL: sta.push(URL); s += "["; stac.push(t); break; case _URL: if (!sta.empty() && sta.top() == URL && !stac.empty()){ s.append("](" + stac.top() + ")"); sta.pop(); stac.pop(); } else{ Wrong = 2; goto ERROR; } break; case IMG: sta.push(IMG); s += " + ")"); sta.pop(); stac.pop(); } else{ Wrong = 2; goto ERROR; } break; case QUOTE: st = getchar(); while (st == '\n') st = getchar(); while (1){ tmp.push_back(st); if (tmp.length() > 7 && tmp.substr(tmp.length() - 8) == "[/quote]") break; if (st == EOF){ Wrong = 3; goto ERROR; } st = getchar(); } tmp = tmp.substr(0, tmp.length() - 8); while (tmp.back() == '\n') tmp.pop_back(); if (s.back() != '\n' && !s.empty()) s.push_back('\n'); if (s.empty()) s.append("> "); if (s.back() == '\n') s.append("> "); for (int i = 0; i < (int)tmp.length(); i++){ s.push_back(tmp[i]); if (tmp[i] == '\n'){ s.append("> "); } } if(tmp.back()!='\n') s.append("\n"); break; case _QUOTE: Wrong = 2; goto ERROR; default: // cout << "ERROR!!!!!!!!!!!!!!!!"; Wrong = 2; goto ERROR; } } else s.push_back(st); st = getchar(); } ERROR: if (Wrong == 2) cout << "Match Error"; else{ if (!sta.empty() || Wrong == 3){ cout << "Unclosed Mark"; } else cout << s; } return 0; }
附赠一组大样例:
输入:
[h1]emm[/h1][quote]q1[/quote][h1][quote][img=1]ii[/img] q2[/quote][/h1] [i][b]ib[/b][/i] [img=1][url=2][/url][h1]cool[/h1][/img]
输出:
# emm # > q1 # > [img=1]ii[/img] > q2 # *__ib__* # cool #](1)
本文作者:wangyishan,转载请注明原文链接:https://www.cnblogs.com/wang-yishan/p/luogu_p2395.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步