【CCF 201509-3】模板生成系统

大致思路

预处理:key "value"

使得key的形式为:{{ key }}   "value"的形式为:value

分别处理每一行

①查找所有可能出现的{{ key }},将其替换为一个特殊的不可打印标记字符,而不是对应的value。把value压入vector<string> val,而这个特殊的不可打印标记字符就是:char(val.size()-1),标记了value的编号。

原因:有点奇技淫巧的感觉,但是这样做有效的避免了递归处理(题目中说{{ key }}不会出现ASCII码小于32的字符)

②处理不合法的{{ key }},将其删除

(这个有点麻烦,废了点脑筋,但是如果不考虑这一点,也能够得到80分)

方法:查找每一对"{{ "和" }}",并考察其中间的内容,如果其中出现了除空格外的可打印字符,则一定是不合法的。

③将所有的标记字符替换为对应的value

感觉是乱搞把这题做出来了,不是特别严谨,细究的话应该还有BUG

C++满分代码(带注释)

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;

int m,n;
string line[105];  //储存待处理的每一行 
string key[105];   //{{ key }} 
string value[105]; //key对应的value
string tmp,t1,t2;
vector<string> val; //储存每一行需要替换的value 

void deal_line(string& str)
{
	string temp;
	val.clear();
	size_t p;
	for(int i=0; i<n; ++i)
	{
		while((p = str.find(key[i])) != string::npos)  //处理存在的{{ key }} 
		{
			val.push_back(value[i]);
			tmp = char(val.size()-1);                 //不可打印标记字符,保证ASCII小于32 
			str.replace(p,key[i].length(),tmp);
		}
	}

	size_t lefts = 0, rights = 0;  // "{{ "和" }}"的位置 
	bool flag;
	while(true)
	{
		lefts = str.find("{{ ", lefts);
		rights = str.find(" }}", rights);
		if(lefts != string::npos && rights != string::npos && lefts < rights) //考察"{{ "和" }}"中间的内容 
		{
			flag = 0;
			for(size_t i=lefts; i<rights; ++i)
				if(str[i] != ' ' && str[i] > 32)  //存在可打印字符 
				{
					flag = 1;
					break;
				}
			if(flag == 1) str.erase(str.begin()+lefts, str.begin()+rights+3); //删除它 
		}
		else break;
	}

	for(int i=0; i<val.size(); ++i)     //将标记字符替换回来 
		str.replace(str.find(char(i)),1,val[i]);
}

int main()
{
	cin>>m>>n;
	cin.get();
	for(int i=0; i<m; ++i)     //输入 
		getline(cin, line[i]);
	
	for(int i=0; i<n; ++i)     //处理  key "value" 
	{
		getline(cin, tmp);
		t1 = "{{ " + tmp.substr(0,tmp.find(" \"")) + " }}"; // t1是{{ key }}
		t2 = tmp.substr(tmp.find("\""));                    // t2是value
		t2.erase(t2.begin());
		t2.erase(t2.end()-1);

		key[i] = t1;
		value[i] = t2;
	}
	
	for(int i=0; i<m; ++i)  //处理每一行 
		deal_line(line[i]);
	
	for(int i=0; i<m; ++i)  //输出 
		cout<<line[i]<<"\n";
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值