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

题目描述

CCF认证 201709-3JSON查询

算法设计

先将整个JSON文本存储到一个字符串s中,然后利用正则表达式将其格式化。正则表达式的语法这里不详细展开(不是我懒,是语法太多塞不下┭┮﹏┭┮),读者可以查阅相关文档。格式化的步骤为:

  1. 去掉s中所有的空格字符
  2. 将两个连续的\"字符转换为单个"字符
  3. 将两个连续的\\字符转换为单个\字符
  4. 在每个,字符后添加一个空格字符
  5. 在每个:字符后添加一个空格字符
  6. 在每个{字符左右均添加空格字符
  7. 在每个}字符左右均添加空格字符

注意2、3步顺序不能颠倒,具体原因读者可以尝试自己思考一下。
然后将整个格式化后的s字符串读入一个stringstream变量中,那么整个字符串s在stringstream中就会自动按空格键分割成多个字符串。然后逐个从该变量中读取字符串,通过深度优先搜索函数递归处理,将键和对应的值存储到unordered_map<string,string>ans中。要注意形如"b": "c"的键值对在ans中存储为b->c,形如"a": {"b": "c"}的键值对在ans中存储为a.b->c。存储成这种形式,查询时直接按查询的字符串在ans中查找即可。具体实现可见代码。

注意点

  1. 同一个对象所有键值对的键必须两两都不相同,但不同对象的键可能相同,同一对象或不同对象的键与值之间可能相同。例如对于以下输入:
4 3
{
"a": {"b": "c"}
"d": {"b": "e"}
}
a
a.b
d.b
b

输出应为

OBJECT
STRING c
STRING e
NOTEXIST
  1. 所有字符串都不是空串。所有作为键的字符串不会包含小数点.。查询时键的大小写敏感。

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;
}

相关文章:

  • 2021-07-01
  • 2021-11-21
  • 2021-11-21
  • 2021-11-21
  • 2021-11-21
  • 2021-11-21
  • 2022-01-14
猜你喜欢
  • 2021-08-21
  • 2022-12-23
  • 2021-11-25
  • 2021-10-12
  • 2022-01-26
  • 2021-09-24
相关资源
相似解决方案