欢迎访问我的CCF认证考试题解目录哦 https://blog.csdn.net/richenyunqi/article/details/83385502
题目描述
算法设计
先将整个JSON文本存储到一个字符串s中,然后利用正则表达式将其格式化。正则表达式的语法这里不详细展开(不是我懒,是语法太多塞不下┭┮﹏┭┮),读者可以查阅相关文档。格式化的步骤为:
- 去掉s中所有的空格字符
- 将两个连续的
\"字符转换为单个"字符 - 将两个连续的
\\字符转换为单个\字符 - 在每个
,字符后添加一个空格字符 - 在每个
:字符后添加一个空格字符 - 在每个
{字符左右均添加空格字符 - 在每个
}字符左右均添加空格字符
注意2、3步顺序不能颠倒,具体原因读者可以尝试自己思考一下。
然后将整个格式化后的s字符串读入一个stringstream变量中,那么整个字符串s在stringstream中就会自动按空格键分割成多个字符串。然后逐个从该变量中读取字符串,通过深度优先搜索函数递归处理,将键和对应的值存储到unordered_map<string,string>ans中。要注意形如"b": "c"的键值对在ans中存储为b->c,形如"a": {"b": "c"}的键值对在ans中存储为a.b->c。存储成这种形式,查询时直接按查询的字符串在ans中查找即可。具体实现可见代码。
注意点
- 同一个对象所有键值对的键必须两两都不相同,但不同对象的键可能相同,同一对象或不同对象的键与值之间可能相同。例如对于以下输入:
4 3
{
"a": {"b": "c"}
"d": {"b": "e"}
}
a
a.b
d.b
b
输出应为
OBJECT
STRING c
STRING e
NOTEXIST
- 所有字符串都不是空串。所有作为键的字符串不会包含小数点
.。查询时键的大小写敏感。
C++代码
#include<bits/stdc++.h>
using namespace std;
unordered_map<string,string>ans;//存储键值对
stringstream all;//按空格字符分割字符串
bool DFS(string key){//递归处理函数
string value;
all>>value;//读取当前的值
if(value=="}")//是右括号
return false;//返回false,表示当前值对象已读取完毕
if(value=="{"){//是左括号
if(key!="")//键不是空字符串
ans[key]="{}";//该键对应的值是一个对象
while(DFS(key));//递归处理值对象
}else{
string v=value.substr(1,value.rfind('"')-1);//除去两端的无用字符后剩余的真正的字符串
if(value.back()==':')//末尾是:字符,表示该字符串是键
DFS((key=="")?v:(key+"."+v));//递归处理其值
else//该字符串是值
ans[key]=v;//将键和值映射起来
}
return true;
}
int main(){
int n,m;
scanf("%d%d%*c",&n,&m);
string s="";
while(n--){//将n行JSON文本读取到字符串s中
string line;
getline(cin,line);
s+=line;
}
s=regex_replace(s,regex(" "),"");//去掉s中所有的空格字符
s=regex_replace(s,regex("\\\\\""),"\"");//将两个连续的\"字符转换为单个"字符
s=regex_replace(s,regex("\\\\\\\\"),"\\");//将两个连续的\\字符转换为单个\字符
s=regex_replace(s,regex(","),", ");//在每个,字符后添加一个空格字符
s=regex_replace(s,regex(":"),": ");//在每个:字符后添加一个空格字符
s=regex_replace(s,regex("\\{")," { ");//在每个{字符左右均添加空格字符
s=regex_replace(s,regex("},?")," } ");//在每个}字符左右均添加空格字符
all<<s;//将字符串s送入all中按空格分割
DFS("");//递归处理
while(m--){//进行查询
cin>>s;
if(ans.find(s)==ans.end())
puts("NOTEXIST");
else if(ans[s]=="{}")
puts("OBJECT");
else
printf("STRING %s\n",ans[s].c_str());
}
return 0;
}