CCF Markdown渲染器 100分代码(超详细)

CCF 2020-6-3 Markdown渲染器 100分

CCF Markdown渲染器 100分代码(超详细)_第1张图片

CCF Markdown渲染器 100分代码(超详细)_第2张图片

CCF Markdown渲染器 100分代码(超详细)_第3张图片
CCF Markdown渲染器 100分代码(超详细)_第4张图片
CCF Markdown渲染器 100分代码(超详细)_第5张图片

题目看起来很复杂,我用一个比较通俗的例子解释一下吧

可以分成三个成分 : 段落 项目 空白行
然后记住如下规则:
1.段落:渲染前要换行,去掉头尾空格
2.项目:如果不是第一个项目,那么渲染前需要换行,如果第一个项目的下一行是“ ”两个空格隔开的那么他也隶属于这个第一个项目的,
但是如果有多个项目连在一起那会变成一个项目列表
3.空白行:起到分割作用看起来美观?

好的我们现在康一个输入样例

   段落1 你正在看写的题解 你觉得很有意思
   
   * 项目1 这是你看到的第一个项目
   
   * 项目2 这是你看到的第二个项目 	  
   * 项目3 项目2项目3共同构成了一个项目列表

   段落2 我我我我我我我我我 我我我我我我我我 我我我我 我我我我我我我我 我我我我我玩完我我我我
              我我 我我 我 我我我我  我我 	 
                    我我我  打了这么久的“我”,其实我还在段落2* 项目4 你你你你 你你你  你 你你你你你 你你你你 你你 你你你你你你你你你你    你你你你你你你
                你你你  你你你你你你 你 看到这一行有两个空格吗。,那你还在项目4中挣扎呢
                  *******在这里打“*”是没用的哦,因为这是项目内容
   
     段落3 为什么我空了两格?,啊没关系,等下我会删掉的。

那么经过MakeDown转换会变成?(假设我们的终端是宽20,嗯第一句话刚好20)
注:可能有些细节没处理好,反正大致意思是这样(看客老爷别真的去数格子啊)

```cpp
 段落1 你正在看写的题解 你觉得很有意思
 
 * 项目1 这是你看到的第一个项目
 
 * 项目2 这是你看到的第二个项目    
 * 项目3 项目2项目3共同构成了一个项目
   列表

 段落2 我我我我我我我我我 我我我我我我
 我我 我我我我 我我我我我我我我 我我我
 我我玩完我我我我            我我 我我
  我 我我我我  我我   我我我  打了这么
  久的“我”,其实我还在段落2* 项目4 你你你你 你你你  你 你你你你
   你 你你你你 你你 你你你你你你你你你
   你    你你你你你你你你你你  你你你
   你你你 你 看到这一行有两个空格吗。,
   那你还在项目4中挣扎呢 *******在这里
   打“*”是没用的哦,因为这是项目内容
  
 段落3 为什么我空了两格?,啊没关系,等
 下我会删掉的。
 

解题思路:

那么:实际上我们可以用状态机来实现。

每次输入的时候判断上一次是什么状态(空白行,段落,项目)
然后再分别根据状态来进行相应处理,无非就是删空格和合并字符两种操作咯

废话不多说,代码:

#include
#include
using namespace std;
struct Markdown{
     
 int type;
 string s;
};//type: 0代表空白行 1 2代表项目 3代表段落
vector<Markdown> vec;//存放经过Markdown处理过后的字符
bool isSpace(string str)//判断是否为空白行
{
     
 for(int i=0;i<str.size();i++)
 {
     
  if(str[i]!=' ')return false;
 }
 return true;
}
int addBlack()//增加空白行
{
     
 Markdown temp;
 temp.s="";
 temp.type=0;
 vec.push_back(temp);
 return 0;
} 
string addStr(string str,int type,bool needpush=true)//增加段落或者项目needpush是判断是否是新增到vec
{
     
 Markdown temp;
 int i,j;
 for(i=0;i<str.size();i++)
 {
     
  if(str[i]!=' ')break;
 }
 for(j=str.size()-1;j>=0;j--)
 {
     
  if(str[j]!=' ')break;
 }
 
 temp.s=str.substr(i,j-i+1);
 temp.type=type;
 if(needpush)
 vec.push_back(temp);
 return temp.s;
}
void addNew(string str,int type)//在一句话后面继续增加(因为可能一个项目或者段落有很多行)
{
     
 if(vec[vec.size()-1].s=="")
 {
     
  vec[vec.size()-1].s=addStr(str,type,false);
 }
 else{
     
  vec[vec.size()-1].s=vec[vec.size()-1].s+" "+addStr(str,type,false);
 }
}
int main()
{
     
 ios::sync_with_stdio(false);//因为大量的数据流所以需要加速
 cin.tie(0);
 cout.tie(0);
 int w;
 cin>>w;//宽度
 int flag=0;//flag对应的是上一行的状态
 string str;//读入的字符串
 while(getline(cin,str))
 {
     
  if(isSpace(str))//如果是空白行 
  {
     
   if(flag!=0)//上一行不是空白行就添加一个空白行 
   {
     
    flag = addBlack();
   }
   continue;
  }
  else if(str.size()>=2&&str[0]=='*'&&str[1]==' ') //项目第一行 
  {
     
   if(flag==3)//上一行是段落则空一行 
   {
     
    addBlack();
   }
   addStr(str.substr(2,str.size()),1); 
   flag=1;
  }
  else if(str.size()>=2&&str[0]==' '&&str[1]==' '&&(flag==1||flag==2))//项目其他行续写
  {
     
   addNew(str.substr(2,str.size()),2);
   flag=2;
  }
  else{
     
  //段落
   if(flag==3)//上一行也是段落所以这一行是上一行段落的续写
   {
     
    addNew(str,3);
   }
   else{
     
     if(flag==1||flag==2)//如果上一行是项目,那需要另起一行,然后新增段落
     addBlack();
     addStr(str,3); 
   }
   flag=3;
  }
 }
 long long res=0;
 if(!vec[vec.size()-1].type)res=-1;//过滤最后一句是空白行 
 for(int i=0;i<vec.size();i++)
 {
     
  str=vec[i].s;
  flag=vec[i].type;
  //cout<
  if(flag==0)
  {
     
   res++;
  }
  else if(flag==3)
  {
     
    int t=0;
    while(t<str.size())
    {
     
     while(1)//过滤空格 
     {
     
      if(t>=str.size()||str[t]!=' ')break; 
      t++;
    }
    t+=w;
    res++;
    }
  }
  else{
     
   if(str.size()==0){
     //处理特殊情况,即项目列表为空,行数+1
    res++;
    continue;
    }
   int t=0;
    while(t<str.size())
    {
     
     
     while(1)//过滤空格 
     {
     
      if(t>=str.size()||str[t]!=' ')break; 
      t++;
    }
    t+=w-3;//因为项目的特性
    res++;
    }
  }
 // cout<<"  res="<
 }
 cout<<res;
}

输入样例1

10
CSP
 
CSP is a real realrealrealrealreal
             competition.
  
Come   and   join   us
  

输出样例1

10

输入样例2

10
* CSP

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

输出样例2

14

你可能感兴趣的:(ccf,算法,数据结构,字符串,markdown,cff,csp)