CCF CSP 201703 3.Markdown
模拟题,其实就是字符串的处理。
- 在
main
函数里处理三种区块,每个区块判别之后再对区块内容做行内处理(调用函数)。 - 区块之间有空行隔开,但是,输入的最后一个区块之后不一定会有空行。第一个空行内需要对其中两种区块(段落、无序列表)作结束处理(因为这两个区块可以是多行)。段落比较特殊,当前行的处理结果(行末加不加
</p>
)由下一行是不是空行决定,所以对段落延迟处理,下行再处理上行的那句段落。 - 设置一个状态变量
block_status
表示当前正在处理的区块类型。 - 注意审题,无序列表是开始插入一行
<ul>
,最后插入一行</ul>
,不是行首行末插入。 - 这道题算比较简单了,规定两种行内结构只会互相嵌套一层,不会多层嵌套,也不会自我嵌套,但是,可以一种行内结构中并列嵌套多个另一种行内结构。不会多层嵌套和不会自我嵌套的好处就是判定结构的标识字符之后的下个最近的该结构的标识字符一定对应当前层(而且这两种结构本身字符也不重复)(不用设置符号栈了)。
- 所以,对两种结构分别各来一次循环就行了,不用想着在一次循环中处理同时处理两种结构(这样费事)。
- 而且这道题其实给的两种结构的标识体整体都不会跨行,很良心了。
printf("%s",str.c_str());
,str
是string
,不能直接应用%s
。freopen("data.txt","r",stdin);
一行搞定直接从文件中读数据,这样省的在控制台输入输出分不清2333,输入数据文件data.txt
要放在和当前cpp
文件同一个文件夹下。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
string str;
string temp; // 输出缓存
int block_status = 0; // 1段落 2标题 3无序列表 0就绪下一个区块
string handleEM(string s)
{
return "<em>" + s.substr(1, s.size() - 2) + "</em>";
}
string handleA(string s)
{
int pos = 0;
for (int i = 1; i < s.size(); i++)
{
if (s[i] == ']')
{
pos = i;
break;
}
}
return "<a href=\"" + s.substr(pos + 2, s.size() - (pos + 2) - 1) + "\">" + s.substr(1, pos - 1) + "</a>";
}
string handleLine(string s)
{
string r1, r2;
for (int i = 0; i < s.size();)
{
if (s[i] == '_')
{
int pos = 0;
for (int j = i + 1; j < s.size(); j++)
{
if (s[j] == '_')
{
pos = j;
break;
}
}
r1 += handleEM(s.substr(i, pos - i + 1));
i = pos + 1;
}
else
{
r1.push_back(s[i]);
i++;
}
}
for (int i = 0; i < r1.size();)
{
if (r1[i] == '[')
{
int pos = 0;
for (int j = i + 1; j < r1.size(); j++)
{
if (r1[j] == ')')
{
pos = j;
break;
}
}
r2 += handleA(r1.substr(i, pos - i + 1));
i = pos + 1;
}
else
{
r2.push_back(r1[i]);
i++;
}
}
return r2;
}
int main()
{
//freopen("data.txt", "r", stdin);
for (; getline(cin, str);)
{
if (str.size() == 0)
{
if (block_status == 3)
{
printf("</ul>\n");
block_status = 0;
}
else if (block_status == 1)
{
printf("%s</p>\n", handleLine(temp).c_str()); // 输出上一行缓存的处理
block_status = 0;
}
continue;
}
if (str[0] == '#')
{
block_status = 2;
int level = 0;
int pos = 0;
for (int i = 0; i < str.size(); i++)
{
if (str[i] != '#') break;
else level++;
}
for (int i = level; i < str.size(); i++)
{
if (str[i] != ' ')
{
pos = i;
break;
}
}
printf("<h%d>%s</h%d>\n", level, handleLine(str.substr(pos, str.size() - pos)).c_str(), level);
block_status = 0;
}
else if (str[0] == '*')
{
if (block_status != 3)
{
block_status = 3;
printf("<ul>\n");
}
int pos = 0;
for (int i = 1; i < str.size(); i++)
{
if (str[i] != ' ')
{
pos = i;
break;
}
}
printf("<li>%s</li>\n", handleLine(str.substr(pos, str.size() - pos)).c_str());
}
else
{
if (block_status != 1)
{
block_status = 1;
printf("<p>");
temp = str;
}
else
{
printf("%s\n", handleLine(temp).c_str());
temp = str;
}
}
}
{ // 若输入最后无空行的话,模拟输入最后有空行
if (block_status == 3)
{
printf("</ul>\n");
block_status = 0;
}
else if (block_status == 1)
{
printf("%s</p>\n", handleLine(temp).c_str()); // 输出上一行缓存的处理
block_status = 0;
}
}
return 0;
}