CSPCCF 20170903 JSON查询

1 篇文章 0 订阅

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 的值。

  1. 这里进行了简化,具体代码也不长。因为我前面处理的时候考虑到一个key或者value字符串必须以""“开始,”""结束,这种方法写在函数
    deal_data中。有兴趣的可以看一看,代码写得不是很工整,原本想先做正确再去考虑优化问题,代码简介问题。现在把代码贴出来,望各位看官找一找另外的90分丢在哪里了,感激不尽。看官们只需要看deal_object和main
    函数就行,加起来大概一百来行,函数deal_data没用到,当然也可以用到。和deal_object相对应,这是一种迭代的处理方式。

  2. 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值