CSPCCF 20170903 JSON 查询问题
我做了这题之后怎么测试都只是10分,字符串的处理方法是按照网上100分的作者写的。
思路如下:
先把json文件的输入转化为一个长string,命名为data。采用递归处理,100分的作者假设此jsons数据的key-value值不包含":", “,” , “{”, “}“等等,只假设其中有[0-9a-zA-Z]以及[”]字符。本人这样处理的,
函数为 int deal_object(string prefix, string& data, int cur, map<string, string> mss), prefix为前缀,初始调用传入”"。data 为json数据字符内容(去除空格,换行符处理)。cur为data中哪个字符开始处理,初始为0。mss为字典。
每个字符进行处理,分多种情况,
-
case 1 “{”,
一个对象的开始,如果此时得到key的长度大于0,就把key保存为一个对象OBJECT,并调用自身进行下一级处理。传入的参数为
cur = i+1, prefix = prefix+"."+key。 -
case 2 " " “,
一个key或者value的开始。当key的长度大于0,就把读取到的字符串当作value,并把key-value存入字典mss中。这里如果读取到”}",需要回退,并continue。 -
[ ] case 3 “}”, 一个对象的结束。返回 i 的值。
-
这里进行了简化,具体代码也不长。因为我前面处理的时候考虑到一个key或者value字符串必须以""“开始,”""结束,这种方法写在函数
deal_data中。有兴趣的可以看一看,代码写得不是很工整,原本想先做正确再去考虑优化问题,代码简介问题。现在把代码贴出来,望各位看官找一找另外的90分丢在哪里了,感激不尽。看官们只需要看deal_object和main
函数就行,加起来大概一百来行,函数deal_data没用到,当然也可以用到。和deal_object相对应,这是一种迭代的处理方式。 -
deal_object 的字符处理思路参照
https://www.cnblogs.com/yxh-amysear/p/8524684.html
。里面没有很好的考虑到key中有[:,.}{]等字符,当然,ccf中也没有这些样例。另,代码里面有些写法是c++11的,给位看官编译的时候加上-std=c++11 这个选项。若发现了很明显的错误,还请QQ联系 1501161071。 备注CCF20170903。多谢各位看官解惑!
// 20170903.cpp
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <map>
using namespace std;
int deal_data(string data, map<string, string> &mss);
int deal_object(string prefix, string& data, int cur, map<string, string> &mss);
void searchmap(map<string, string> &mss, string key);
void print_map(map<string, string>& mss);
int main(int args, char *argv[]){
char in[105*105];
string buf;
stringstream ss;
map<string, string> mss;
vector<string> vec_keys;
int m,n;
int i = 0;
cin >> n >> m;
cin.sync();
while(n--){
//cin >> buf;
getline(cin, buf);
string str(buf);
ss << buf << " ";
for(int k=0;k<str.length();k++)
{
if(str[k]=='\\')
in[i++] = str[++k];
else if(str[k] == ' ' || str[k] == '\n')
continue;
else{
in[i++] = str[k];
}
}
}
//string data(ss.str());
in[i] = '\0';
string data(in);
//deal_data(data, mss); // 若采用deal_data, 就需要使用 dela_data(ss.str(), mss)
deal_object("", data, 0, mss);
while(m--){
string stmp;
cin>> stmp;
vec_keys.push_back(stmp);
}
// print_map(mss);
for(string key : vec_keys){
searchmap(mss, key);
}
return 0;
}
int deal_data(string data, map<string, string> &mss){
int i = -1, out = -1;
//int len = data.length();
string key="", value = "";
vector<string> vec_str;
string prefix = "";
int len = data.find_last_not_of(' ');
while(i < len){
while(data[++i] == ' '); // 去除空格
if(data[i] == '{'){ // 一个对象的开始
if(key.length() > 0){
mss[prefix+key] = "OBJECT";
vec_str.push_back(key);
prefix += key;
prefix += '.';
key.clear();
}
//while(data[++i] != '"'); // 找到元素项开始的位置
}
else if(data[i] == '"'){ // 一个元素项的开始
string stmp = "";
while(data[++i] != '"'){
if(data[i] == '\\'){
stmp += data[++i];
}
else {
stmp += data[i];
}
}
if(key.length() > 0 ){
value = stmp; mss[prefix+key] = "STRING "+value;
key.clear(); value.clear();
}
else{
key = stmp;
}
}
else if(data[i] == '}'){
// 找到逗号分隔符
int out = vec_str.size();
if( out > 0){
int tmp = vec_str.back().size();
prefix.erase( prefix.length() - tmp - 1, tmp +1);
vec_str.pop_back();
}
continue;
}else if(data[i] == ','){
//data[i] == ','
continue;
}else if(data[i] == ':'){
if(value.empty())
;
else
return -1; // 解析出现错误
}
/*
while(data[++i] != '"'){
if(data[i] == '\\'){
key += data[++i];
}
else {
key += data[i];
}
}
// 找到 :
while(data[++i] != ':');
// 找到第一个不是 空格的字符
while(data[++i] == ' ') ;
if(data[i] == '{'){
i -= 1;
//out += 1;
mss.insert(pair<string, string>(prefix+key, "OBJECT"));
prefix += key + ".";
vec_str.push_back(key);
key.clear();
continue;
}
else if(data[i] == '"'){
while(data[++i] != '"'){
if(data[i] == '\\'){
value += data[++i];
}
else{
value += data[i];
}
}
mss.insert(pair<string, string>(prefix+key, "STRING "+value));
key.clear();
value.clear();
}
// 解析一条项目后找到下一个不是空格的字符
while(data[++i] != ',' && data[i] != '}');
if(data[i] == '}'){
// 找到逗号分隔符
if( out > 0){
int tmp = vec_str.back().size();
prefix.erase( prefix.length() - tmp - 1, tmp +1);
vec_str.pop_back();
}
out -= 1;
while(data[++i] == ' ' && out > 0 );
if(data[i] == ',')
;
else if(data[i] == '}'){
i -= 1;
if( out > 0){
int tmp = vec_str.back().size();
prefix.erase( prefix.length() - tmp - 1, tmp +1);
vec_str.pop_back();
out -= 1;
}
continue;
}
}
else if(data[i] == ','){
// 一条规则解析完毕
}
*/
//cout << prefix+key << " "<< value <<endl;
//mss.insert(pair<string, string>(prefix+key,"STRING " +value));
//key.clear();
//value.clear();
}
return 0;
}
void searchmap(map<string, string> &mss, string key){
std::map<string, string>::iterator it;
//string result = mss[search];
it = mss.find(key);
if(it == mss.end()){
cout<<"NOTEXIST"<<endl;
}
else{
cout<<it->second<<endl;
}
}
void print_map(map<string, string> &mss){
for(pair<string, string> it : mss){
cout<<it.first<<" "<<it.second<<endl;
}
}
int deal_object(string prefix, string& data,int cur, map<string, string> &mss){
int len = data.find_last_not_of(' ');
string key="", value="";
if(prefix.length() > 0)
prefix += ".";
for(int i = cur; i < len; i++ ){
if(data[i] == '"' && key.length() > 0){
string stmp = "";
i++;
while(data[i] != ',' && data[i] != '}' && i < len){
stmp += data[i++];
}
stmp.erase(stmp.length() - 1);
value = stmp; mss[prefix+key] = "STRING "+value;
key.clear(); value.clear();
i-- ; continue;
}
else if(data[i] == '"' && key.length() == 0){
string stmp = "";
i++;
while(data[i] != ':' && i < len){
stmp += data[i++];
}
stmp.erase(stmp.length() - 1);
key = stmp;
continue;
}
else if(data[i] == ':'){
continue;
}else if(data[i] == '{'){
i = deal_object(prefix+key, data, i+1, mss);
if( key != "")
mss[prefix+key] = "OBJECT";
key.clear();
continue;
}
else if(data[i] == '}'){
return i;
}
else if(data[i] == ','){
continue;
}
else{
continue;
}
}
return len;
}