202006-3 CCF CSP認證 Markdown渲染器(詳解大模擬)

題目連接:(因爲要提供我的帳號,才能進入,貼一個地址吧)https://passport.ccf.org.cn/

題目大意:

          (我的感受這個題,有些地方表達不夠清晰。)ios

   從前有個MarkDown渲染器。它能把我寫的亂七八糟的文本,轉化成漂漂亮亮的那種具體,怎麼轉換呢?c++

  •     本題有段落和項目之分,你好比說我上邊說的這兩行廢話就是段落。  而什麼是項目呢?就是你好比本行,前邊有一個點點,這就是項目,我這個項目還沒說完,就會自動切行,你好比如今。
  •     而當我先有了另外一個點點也就是另外一個項目,這兩個點點,就組成了一個項目列表,中間不須要空行分割。

當我結束了上邊的項目列表,下邊要接段落的時候,中間要空一行。數組

對於段落的處理:

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

        2. 開始打印,當這一行夠了w個字符要換行。this

        3. 碰到一個或連續的多個空行要切一個空行。spa

        4. 若是換的新行,開始是空格那麼就要刪掉這些空格。code

對於項目的處理:

        1. 「* 」 這個表明了一條項目的開始,也就是那個點點,碰到這個東西要開始一個新的列表。ci

        2. 「  」 兩個空格表明了隸屬於這個項目的內容,也就是說,看似是輸入了兩行,實際上是連在一塊兒的。get

        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


*/
相關文章
相關標籤/搜索