CCP-CSP认证考试 201703-3 Markdown c/c++题解

题目描述

题解:

这道题我做了挺长时间了(看起来挺简单的,但是做起来还是有点难度),结果还只有70分
我只说下我的过程:
1、只考虑区块(标题、无序列表、段落): 4个测点,正好拿了40分
2、考虑区块内的强调:多了两个测点,60分
3、考虑区块内的超链接:只多过了一个测点,应该是有错误,70分(最后的分数,懒得调试了)
注意点:

  1. 输出时删除所有分隔区块的空行,也就是没有空行
  2. 强调 和 超链接是行内,也就是是包括在区块中的(标题、无序列表、段落)
  3. 解题策略:拿到这种题目不要想着拿满分的,以这种思路去写代码,会完全的考虑大多数情况,但是实际上这样会很麻烦,还不如从最小的点开始,一步步的调试优化。

代码(70分)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll  INF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double E = exp(1.0);
const int MOD = 1e9+7;
const int MAX = 1e5+5;
vector  markdown;
//vector  html;

// 将markdown的强调(其实就是斜体)形式转换为html形式:__item__ => item
bool judgeEmphasize(string mkdown)
{
    // 判断有无强调(下划线)
    int len = mkdown.length();
    for(int i = 0; i < len; i++)
    {
        if(mkdown[i] == '_')
            return true;
    }
    return false;
}
string emphasize(string mkdown)
{
    int flag = 0;// 0 ->            1 -> 
    int len = mkdown.length();
    int i = 0;
    while(1)
    {
        /*
        如果遇到'_' 且 flag = 0: 将'-'替换成""、flag = 1
        如果遇到'_' 且 flag = 1: 将'-'替换成""、flag = 0
        */
        if(mkdown[i] == '_')
        {
            if(flag == 0)
            {
                mkdown.replace(i,1,"",4);
                flag = 1;
                i += 4;
            }
            else
            {
                mkdown.replace(i,1,"",5);
                flag = 0;
                i += 5;
            }
        }
        else
        {
            i++;
        }
        if(i == mkdown.length())
            break;
    }
    return mkdown;
}

// 将markdown的超链接形式转换为html形式:[item](www.baidu.com) => item
string hyperlink(string mkdown)
{
    int num = 0;// 计算'[' or ']' or '(' or ')'的数量,如果为偶数个即有超链接
    int len = mkdown.length();
    for(int i = 0; i < len; i++)
    {
        if(mkdown[i] == '[' || mkdown[i] == ']' || mkdown[i] == '(' || mkdown[i] == ')')
        {
            num++;
        }
    }
    if(num % 2 != 0 || num == 0)
    {
        // 如果没有超链接,直接返回
        return mkdown;
    }
    else
    {
        int index1,index2,index3,index4;
        for(int i = 0; i < len; i++)
        {
            if(mkdown[i] == '[') index1 = i;
            if(mkdown[i] == ']') index2 = i;
            if(mkdown[i] == '(') index3 = i;
            if(mkdown[i] == ')') index4 = i;
        }
        string str1 = mkdown.substr(index1+1,index2-index1-1);
        string str2 = mkdown.substr(index3+1,index4-index3-1);
        //cout << str1 << " " << str2 << endl;
        string link =  "" + str1 + "";
        //cout << link << endl;
        mkdown.replace(index1,index4-index1+1,(char *)link.c_str(),link.length());
        return mkdown;
    }
}

// 将markdown的段落形式转换为html形式:正常的分段 => 

void paragraph(int startRow,int endRow,int num) { /* 段落可能会有连续的几行,每一行放到一个string里面, 1. 如果只有一行 num = 1: markdown[startCol]的前面要加个

,后面加个

2. 如果有多行 num >= 2: markdown[startCol]的前面要加个

, markdown[endCol]的后面要加个

*/ if(num == 1) { markdown[startRow] = "

" + markdown[startRow] + "

"; } else { markdown[startRow] = "

" + markdown[startRow]; markdown[endRow] = markdown[endRow] + "

"; } } // 将markdown的标题形式转换为html形式:# =>

string itos(int i) { vector tmp; while(i) { tmp.push_back(i%10); i /= 10; } string str = ""; int len = tmp.size(); for(int i = len - 1; i >= 0; i--) { str += ('0' + tmp[i]); } return str; } string title(string mkdown) { int index = 0;// 判断有几个'#' while(mkdown[index] == '#') index++; string content = mkdown.substr(index+1); // 标题属于区块,区块就可能有强调或者超链接 content = hyperlink(content); content = emphasize(content); string res = "" + content + ""; return res; } // 将markdown的无序列表形式转换为html形式:* item =>
  • item
vector unorderList(int startRow,int endRow,int num) { // 对于无序列表的处理: vector res; res.push_back("
    "); for(int i = startRow; i <= endRow; i++) { int index = 0; while(!isalnum(markdown[i][index])) index++; string tmp = markdown[i].substr(index); // 无序列表项属于区块,区块就可能有强调或者超链接 tmp = hyperlink(tmp); tmp = emphasize(tmp); res.push_back("
  • " + tmp + "
  • "); } res.push_back("
"); return res; } /* Markdown 文本到 HTML 代码的转换 */ int main() { /* ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); */ string str; while(getline(cin,str)) { markdown.push_back(str); } int rowNums = markdown.size(); /* for(int i = 0; i < rowNums; i++) { cout << markdown[i] << " " << markdown[i].size() << endl; } */ int i = 0; while(i < rowNums) { //cout << "i: " << i << " markdown[i][0]:" << markdown[i][0] << endl; if(markdown[i][0] == '#')// 只考虑有标题 { // cout << "标题的情况" << endl; //html[i].push_back(title(markdown[i]); cout << title(markdown[i]) << endl; i++; } else if(markdown[i][0] == '*')// 如果遇到了列表,要看看下面有几个"*" { // cout << "列表的情况" << endl; int num = 0;// 记录下"*"的个数 int j = i; while(j < rowNums && markdown[j][0] == '*') { j++; num++; } // 这里可能要返回多行,所以用vector 来保存 vector res(num+2); res = unorderList(i,j-1,num);// 从markdown的i~j-1行,总共num个*,也就是num行数据 int len = res.size(); for(int k = 0; k < len; k++) { cout << res[k] << endl; } i = j; } else if(markdown[i].size() != 0)// markdown[i][0],也就是第一个字符,如果不是'#',也不是'*',那一定是段落的形式,前面后面加个

{ // cout << "段落的情况" << endl; // 段落也要考虑有几行 int num = 0; int j = i; while(j < rowNums && markdown[j].size() != 0) { j++; num++; } // 调用段落函数以后吗,原数组markdown的行就会加上段落的标志 paragraph(i,j-1,num); for(int k = i; k <= j-1; k++) { string tmp = markdown[k]; // 段落属于区块,区块就可能有强调或者超链接 tmp = hyperlink(tmp); tmp = emphasize(tmp); cout << tmp << endl; } i = j; } else { //cout << "空的情况" << endl; i++; } } /* for(int i = 0; i < rowNums; i++) { cout << html[i] << endl; }*/ return 0; }

你可能感兴趣的:(#,CCF-CSP认证考试)