看似最终只要写50多行花不了多少时间,但是实际上是要花好多时间的。
其中,map<string,string>可以实现一层查询。
多层查询是个难点,这里我们可以将类似于address.city的查询直接当做一个键。这样一来只要在map中找就可以了。
其次是对STL的熟练度的考察。
一,string
1.isspace函数可以检验空格和tab!
2.substr(x)返回从x开始的后缀(包含x)
substr(x,n)返回从x开始的n个字符的子串(包含x)
3.erase(int x=0,int n)从x开始删除, 要删除字符的长度为n, 返回为修改后的string对象引用
erase(const_iterator it)删除迭代器位置处的单个字符, 并返回下个元素的迭代器
erase(const_iterator first, const_iterator last)删除迭代器[first, last)区间的所有字符,并返回下个元素的迭代器
4.find(char c,int x=0)从x开始找,返回c的下标,未找到返回npos
类似的还有find(string s,int x=0) find(char *s,int x)
用string::npos做EOF,表示find函数未找到
二,map
1.find()返回被查找元素的位置,没有则返回map.end()。
2.count()如果有被查找元素,返回1;否则,返回0。(map中没有相同元素)
#include<bits/stdc++.h>
using namespace std;
map<string,string>mp;
void work(string&json,string&res){
string key,value;
for(int i=0;i<json.size();i++){
if(json[i]=='"'){
int j=json.find(':',i+1);
key=json.substr(i+1,j-i-2); //j-i+1-3 一对冒号加引号是3
if(res!="")key=res+"."+key;
if(json[j+1]=='"'){ //value是纯字符串
string::size_type k=json.find(',',j+2);
if(k==string::npos){//value是最后一个
k=json.find('}',j+2);
}
value=json.substr(j+2,k-j-3);
i=k;
}
else{ //value是对象
int cnt=1;i=j+3;
while(cnt!=0){
if(json[i]=='}')cnt--;
else if(json[i]=='{')cnt++;
i++;
}
value=json.substr(j+1,i-j-1);
work(value,key);
}
mp[key]=value;
}
}
}
int main(){
int n,m;
string tmp,line,json,res;//先将输入转化为一个字符串
cin>>n>>m; getchar();//吸收换行符
for(int i=0;i<n;i++){
getline(cin,line);
for(int i=0;i<line.size();){
if(isspace(line[i])){line.erase(i,1);}
else if(line[i]=='\\'){line.erase(i,1);i++;}
else i++;
}
json+=line;
}
work(json,res);
for(int i=0;i<m;i++){
cin>>tmp;
if(mp.find(tmp)!=mp.end()){
if(mp[tmp][0]=='{')cout<<"OBJECT"<<endl;
else cout<<"STRING "<<mp[tmp]<<endl;
}
else cout<<"NOTEXIST"<<endl;
}
return 0;
}
关于输入那部分的处理用迭代器的写法是这样的:
for(string::iterator it=line.begin();it!=line.end();){
if(isspace(*it))it=line.erase(it);
else if(*it=='\\')it=line.erase(it)+1;
else it++;
}
参考传送门