201709-3 JOSN查询
题目
思路
用map<string,string> 存对象的键值对,详见代码。
AC代码如下
#include<iostream>
#include<string>
#include<map>
using namespace std;
map<string,int> index;//存对象的索引
map<string,string> objs[100];//存对象
string ans;
int p=1;
void trans(string &str){//去掉空格,同时把字符串两边的引号"换掉
for(int i=0;i<str.size();i++){
if(str[i]==' ') str.erase(i--,1);//删完i要减一,不然会跳过一个字符
else if(str[i]=='\\'){//遇到一个反斜杠'\',删掉它,同时不要动i,自动跳过了'\'后面的字符
str.erase(i,1);
}
else if(str[i]=='\"'){
//遇到字符串的引号,把它换成一个其它的东西,避免字符串内部的引号影响之后的分析,这个东西必须很特别,
//要保证它不会在字符串内部出现,也不可以是会在其它地方出现的符号,你可以选择'\n'之类的,我选了自己的ID
str.replace(i,1,"kkry2333");
i+=7;//替换之后更新i
}
}
}
void jsonSplit(string str,int x,string addtion){//递归分析键值
int s=1;
while(s<str.size()){
int t=str.find("kkry2333",s+1);//找引号标识(字符串后端那个)(键)
if(t==string::npos) break;
s+=8;//越过引号标识
string Key=str.substr(s,t-s);
t+=7;//越过引号标识
if(str[t+2]=='{'){//值如果是对象
objs[x][Key]="";//将其值置为空,方便查询时的判断
s=t+2;//s记录对象的起点
int ss=str.find("{",t+3);//找下一个左括号
t=str.find("}",t+1);
while(ss!=string::npos&&t>ss){//如果有左括号在前面,说明还有嵌套,一直往后找,找到当前层次的右括号为止
t=str.find("}",t+1);
ss=str.find("{",ss+1);
}
Key+=addtion;//键上加个标识,避免不同层次对象里键的同名
index[Key]=p;
jsonSplit(str.substr(s,t-s+1),p++,addtion+"2333kkry");//每往嵌套一层,就加长一个标识
s=t+2;
}
else {//如果是字符串
s=str.find("kkry2333",t+3)+7;
objs[x][Key]=str.substr(t+10,s-t-10-7);//记录
s=s+2;
}
}
}
int findValue(string str,int x,string addtion){//求解
int s=str.find(".",0);
if(s==string::npos){//返回值0表示不存在,1表示是对象,2表示是字符串
if(objs[x].find(str)==objs[x].end()) return 0;
else if(objs[x][str]=="") return 1;
ans=objs[x][str];//记录查询结果
return 2;
}
string Key=str.substr(0,s);
if(objs[x].find(Key)==objs[x].end())return 0;
Key+=addtion;//键加上标识再递归查找
if(index.find(Key)==index.end()) return 0;//无该对象
return findValue(str.substr(s+1,str.size()-s-1),index[Key],addtion+"2333kkry");
}
int main(){
int n,m;
cin>>n>>m;
cin.get();
string obj,str;
while(n--){
getline(cin,str);
obj+=str;
}
trans(obj);
jsonSplit(obj,0,"2333kkry");
while(m--){
getline(cin,str);
switch(findValue(str,0,"2333kkry")){
case 0:cout<<"NOTEXIST"<<endl;break;
case 1:cout<<"OBJECT"<<endl;break;
default:cout<<"STRING "<<ans<<endl;
}
}
return 0;
}