CCF认证201509-3模板生成系统

欢迎访问我的CCF认证考试题解目录哦 https://blog.****.net/richenyunqi/article/details/83385502

题目描述

CCF认证201509-3模板生成系统

算法设计

这道题可以利用正则表达式来解决(好吧,好像csp上关于这种文本处理的题目我都是用正则表达式来解决的-_-||,主要是正则表达式的功能太强大了,让人爱不释手,等有时间我专门写一篇博客来详细阐述一下正则表达式的常用函数和语法)。这道题如果直接用正则表达式对html文本中的标记进行替换,会造成超时,所以这里我们采取匹配成功直接输出对应字符串的方法。
首先将html文本逐行读取到vector<string>html中,接着将标记的变量名和值进行分割并存储到unordered_map<string,string>strReplace中。遍历html中的每行字符串,利用正则表达式中的regex_search函数进行标记匹配,如果匹配成功,将变量名截取下来,查看在strReplace中是否有对应的键,如果有,输出对应的值;如果没有,输出空字符串。对于没有匹配成功的其他字符串,直接按原样输出即可。
正则表达式可能不太好掌握,我另外又写了一份同样可以AC的使用stringfind函数的代码,方便读者对比理解。
具体实现可见代码。

使用正则表达式的C++代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    int m,n;
    scanf("%d%d%*c",&m,&n);
    vector<string>html;
    string line;
    while(m--){
        getline(cin,line);
        html.push_back(line);
    }
    unordered_map<string,string>strReplace;
    while(n--){
        getline(cin,line);
        int t=line.find(' ');//查找第一个空格字符的位置,该空格字符可以用来分割变量名和值
        string s1=line.substr(0,t),s2=line.substr(t+2,line.size()-t-3);//s1存储变量名,s2存储去除首尾"字符的值
        strReplace[s1]=s2;//将变量名和值对应起来
    }
    smatch result;
    for(string&i:html){
        auto j=i.cbegin();//传入regex_search的迭代器需要是const_iterator类型
        while(regex_search(j,i.cend(),result,regex("\\{\\{ ([^\\}]+) \\}\\}"))){//在字符串中查找有子字符串匹配成功
            for(;j!=result[0].first;++j)//输出从开始搜索的位置到匹配成功的子字符串的起始位置的所有字符
                printf("%c",*j);
            auto k=strReplace.find(result[1]);//查看strReplace中是否有相应的变量名
            printf("%s",k!=strReplace.end()?(k->second).c_str():"");//输出变量名对应的值
            j=result[0].second;//将下一个开始搜索位置更新为当前匹配成功的子字符串的末尾位置
        }
        for(;j!=i.cend();++j)//输出从最后一个匹配成功的子字符串的末尾位置到整个字符串末尾位置的所有字符
            printf("%c",*j);
        puts("");//换行
    }
    return 0;
}

使用string的find函数的C++代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    int m,n;
    scanf("%d%d%*c",&m,&n);
    vector<string>html;
    string line;
    while(m--){
        getline(cin,line);
        html.push_back(line);
    }
    unordered_map<string,string>strReplace;
    while(n--){
        getline(cin,line);
        int t=line.find(' ');//查找第一个空格字符的位置,该空格字符可以用来分割变量名和值
        string s1=line.substr(0,t),s2=line.substr(t+2,line.size()-t-3);//s1存储变量名,s2存储去除首尾"字符的值
        strReplace[s1]=s2;//将变量名和值对应起来
    }
    for(string&i:html){
        int j=0;
        for(j=0;j<i.size();){
            int k1=i.find("{{ ",j),k2=i.find(" }}",j);//查找"{{ "和" }}"的位置
            if(k1==string::npos&&k2==string::npos)//没有匹配成功的子字符串,跳出循环
                break;
            for(;j<k1;++j)//输出从开始搜索的位置到匹配成功的子字符串的起始位置的所有字符
                printf("%c",i[j]);
            auto k=strReplace.find(i.substr(k1+3,k2-k1-3));//查看strReplace中是否有相应的变量名
            printf("%s",k!=strReplace.end()?(k->second).c_str():"");//输出变量名对应的值
            j=k2+3;//将下一个开始搜索位置更新为当前匹配成功的子字符串的末尾位置
        }
        for(;j<i.size();++j)//输出从最后一个匹配成功的子字符串的末尾位置到整个字符串末尾位置的所有字符
            printf("%c",i[j]);
        puts("");//换行
    }
    return 0;
}