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 += "![";
stac.push(t);
break;
case _IMG:
if (!sta.empty() && sta.top() == IMG && !stac.empty()){
s.append("](" + stac.top() + ")");
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__*
![[](2)# cool #](1)
本文作者:wangyishan,转载请注明原文链接:https://www.cnblogs.com/wang-yishan/p/luogu_p2395.html