202006-3 CCF CSP认证 Markdown渲染器(详解大模拟)

题目链接:(由于要提供个人账号,才能进入,贴一个地址吧)https://passport.ccf.org.cn/

题目大意:

          (个人感觉这个题,有些地方表达不够清晰。)

   从前有个MarkDown渲染器。它能把我写的乱七八糟的文本,转化成漂漂亮亮的那种具体,怎么转换呢?

  •     本题有段落和项目之分,你比如说我上边说的这两行废话就是段落。  而什么是项目呢?就是你比如本行,前边有一个点点,这就是项目,我这个项目还没说完,就会自动切行,你比如现在。
  •     而当我先有了另一个点点也就是另一个项目,这两个点点,就组成了一个项目列表,中间不需要空行分割。

当我结束了上边的项目列表,下边要接段落的时候,中间要空一行。

对于段落的处理:

        1. 去掉每行行首行尾的空格。

        2. 开始打印,当这一行够了w个字符要换行。

        3. 碰到一个或连续的多个空行要切一个空行。

        4. 如果换的新行,开始是空格那么就要删掉这些空格。

对于项目的处理:

        1. “* ” 这个代表了一条项目的开始,也就是那个点点,碰到这个东西要开始一个新的列表。

        2. “  ” 两个空格代表了隶属于这个项目的内容,也就是说,看似是输入了两行,其实是连在一起的。

        3.  渲染时吧开头的两个字符去掉,然后当段落处理。注意保持缩进。

        4.  如果渲染一个项目的同时碰到了另一个项目,那么不需要换行,直接开始渲染。

        5. 如果碰到了一个段落或者空行,那么要先结束当前列表的渲染,然后切个空行,再开始段落。

处理细节(坑):

        1.  一上来就输入好多个空行的话要忽略,也就是说从第一个非空行开始渲染,这个题目没有说清楚。还以为要先切一下。

        2. 由于时限给了1s,面对大量的string输入,很容易超时,关同步流会优化很多。

        3. 当出现空项目的时候是不需要切行的,也就是说和上边的属于同一个项目列表,只不过内容是空的。

   

       博主的实现方法核心思想就是:

   1.  先判断一下本行是什么,段落还是项目 

   2. 再记录一下上一行是什么,项目还是段落

   3. 根据两行的类别,判断需不需要切空行,需不需要添加缩进,然后去首位空格,开始添加字符。

代码:最后输出了渲染后的文本,方便读者可以进行对拍。(ans数组可以扔掉,但是为了输出结果,方便观察输出)

     

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll MAXN = 5e5+5;
//string s[50005];
string ans[500005];
string s;
int w;
void del_sp(int tot){  // 去首尾空格
    int len = s.size();
    int idx1 = 1,idx2 = 0;
    for(int i=0;i<len;i++){
        if(s[i]!=' '){
            idx1 = i;break;
        }
    }
    for(int i=len-1;i>=0;i--){
        if(s[i] != ' '){
            idx2 = i;break;
        }
    }
    string k = "";
    for(int i=idx1;i<=idx2;i++){
        k += s[i];
    }
    s = k;
}
int num = 0,all = 0;
string k = "";
void add(char c)  //添加字符
{
    k += c; //  <--this
    num++;
    if(num == w){   //  1.
        ans[++all] = k;
        //all++;
        k = "";
        num = 0;
    }
}
void enter(int h)    //2. 切行
{
    //cout<<h<<" ^ "<<endl;
    if(num!=0){
        ans[++all] = k;
        //all++;
    }
    //all++;
    ans[++all] = "";
    k = "";
    num = 0;
}
bool check_sp(int x,int idx)   //判空行
{
    for(int i=idx;i<s.size();i++){
        if(s[i] != ' ')return false;
    }
    return true;
}
int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>w;
    getline(cin,s);
    int fg = 0,i=0;
    int flag = 0;// 0 段落  1 列表  3空行 上一行是什么
    while(getline(cin,s) != NULL){
        int len = s.size();
        if(check_sp(i,0)){ // 空行
            flag = 3;
            continue;
        }
        if(flag == 3&&fg){
            enter(i);
        }

        int flag2 = 0; // 本行是什么   1 列表  0 段落
        if(len>=2 && s[0] == '*' && s[1] == ' '){
            flag2 = 1;
            s = s.substr(2,len-2);
            if(flag == 1 && num!=0){
               // all++;
                ans[++all] = k;        //3.
               k = "";
                num = 0;
            }
            if(flag == 0 ){
                if(fg!=0)enter(i);
            }
            add('.');add('.');add('.');
        }
        else if(len >=2 && s[0] == ' ' && s[1] == ' '){
            if(flag == 1){ // 列表
                s = s.substr(2,len-2);
                flag2 = 1;
                if(num == 0){
                    add('+');add('+');add('+');
                }
            }

        }

        del_sp(i),len = s.size();
        if(flag == 0){
            if(flag2 == 0 && num!=0)add(' ');
        }
        if(flag == 1){
            if(flag2 == 0){
                enter(i);
            }
            if(flag2 == 1){
                if(num>3)add(' ');
            }
        }
        //cout<<i<<" * "<<flag<<" * "<<flag2<<endl;
        for(int j=0;j<len;j++){
            if(num == 0 && flag2 == 1){
                add('+');add('+');add('+');
            }
            if(flag2 == 0){
                if(num == 0 && s[j] == ' ')continue;
            }
            if(flag2 == 1){
                if(num == 3 && s[j] == ' ')continue;
            }

            add(s[j]);
        }
        flag = flag2;
        fg = 1;
    }
    if(num!=0){   //4.
        //all++;
        ans[++all] = k;
    }
    cout<<"------------"<<endl;
    for(int i=1;i<=all;i++){
        cout<<ans[i]<<endl;
    }
    cout<<all<<endl;
}



/*
4
asjcaojca
aaa
a
*/

/*
10
CSP

CSP is
a real realrealrealrealreal
     competition.


Come   and   join   us


*/

/*
10
* CSP

*   CSP is
  * a real
     competition.
* 
  * Come!   and   join.
*Tel:
* 12345
* 
*/

/*
4
* aaaa
*bbb
  ccc
* dd
    eee
*ff


*/

猜你喜欢

转载自blog.csdn.net/qq_41645482/article/details/107825536