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;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值