CCF CSP 202006-3 Markdown渲染器

理解

对于普通文本

  • 处理文本时:
    • 去掉每行首尾的连续空格
  • 渲染时:
    • 段落和其余段落/项目列表之间空出一行
    • 超出一行大小则渲染至下一行
    • 如果余下的文本以空格开头,则删除所有空格

对于列表

  • 处理列表时:

    • 删除列表之间的空白行
    • 删除开头不是两个空格的行(两个空格就代表该行最前面有一个空格)
  • 渲染时:

    • 把列表和段落/列表之间空出一行
    • 空格 星号 空格 和两个空格转换为 空格 列表点 空格
    • 每一个列表的非第一行首都要插入3个空格

注意:在渲染列表时,要注意每一行只有n-3个字符

代码

#include <iostream>
#include <vector>

using namespace std;
struct Markdown{
    
    
    int type;
    string s;
};

bool isspace(string str){
    
    //判断是否为空行
    for(int i=0;i<str.length();i++)
        if(str[i]!=' ')
            return false;
    return true;
}
string standard(string str){
    
    
    int pos1=0,pos2=str.length() - 1;
    for(int i=0;i<str.length();i++){
    
    
        if(str[i]!=' '){
    
    
            pos1=i;
            break;
        }
    }
    
    for(int i=str.length()-1;i>=0;i--){
    
    
        if(str[i]!=' '){
    
    
            pos2=i;
            break;
        }
    }
    string res=str.substr(pos1,pos2-pos1+1);
    return res;
}

vector<Markdown> article;
int main() {
    
    
	ios::sync_with_stdio(false);//加速了cin速度,否则造成超时
    int n;
    cin>>n;
    string str;
    //边输入边渲染
    
    while(getline(cin,str)){
    
    //通过第一行判断是什么文本
        if(!isspace(str))//不是空行
            break;
    }//不断输入

    if(str.length()>=2&&str[1]==' '&&str[0]=='*')//列表文本
        article.push_back({
    
    1,standard(str.substr(2))});
    else//普通文本
        article.push_back({
    
    2,standard(str)});
    bool check=false;
    
    while(getline(cin,str)){
    
    
        if(isspace(str))//是空行
            check=true;
        else{
    
    
            if(check){
    
    //上一行是空行,该行非空,直接插入
                check=false;
                if(str.length()>=2&&str[1]==' '&&str[0]=='*')
                	article.push_back({
    
    1,standard(str.substr(2))});
                else//普通文本
                    article.push_back({
    
    2,standard(str)});
            }
            else{
    
    //上一行非空,那就要考虑是否是同一段/同一列表了
                Markdown &temp=article.back();
                if(temp.type==1||temp.type==3){
    
    //列表情况
                    if(str.length()>=2&&str[1]==' '&&str[0]==' '){
    
    
                        //直接连接上
                        temp.s+=" ";
                        temp.s += standard(str.substr(2));
                    }
                    else if(str.length()>=2&&str[1]==' '&&str[0]=='*'){
    
    
                        //代表非列表第一行
                        article.push_back({
    
    3,standard(str.substr(2))});
                    }
                    else{
    
    //正常段落
                        article.push_back({
    
    2, standard(str)});
                    }
                }
                else{
    
    
                    if(str.length()>=2&&str[1]==' '&&str[0]=='*')
                        //开启新列表
                        article.push_back({
    
    1,standard(str.substr(2))});
                    else{
    
    
                        temp.s+=" ";
                        temp.s += standard(str);
                    }
                }
            }
        }
    }
    long long ans=0;
    for(int i=0;i<article.size();i++){
    
    
        string& str=article[i].s;
        if(article[i].type!=3&&i>0){
    
    //遇到
            ans++;
        }
        if(article[i].type!=2){
    
    
            if(str.size()==0){
    
    
                ans++;//空项目++
            }
            else{
    
    //注意同一项目第一行 空格 * 空格 /非第一行要插入三个空格
                for (int i = 0; i < str.length(); i += (n - 3)){
    
    
                    while(i<str.length()&&str[i]==' ')
                        i++;
                    ans++;
                }
            }
        }
        else{
    
    //代表普通文本
            for (int i = 0; i < str.length(); i += n){
    
    
                while(i<str.length()&&str[i]==' ')
                    i++;
                ans++;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Cindy_00/article/details/108431775
今日推荐