CCF JSON查询 Java 完美满分 详解

CCF JSON查询 Java 完美满分 详解

主要想法就是用一个列表当做像栈一样缓存着键,遇到键字符串的时候就把它与上一层的键结合成嵌套形式存入列表,这样,列表的最后一个元素总是代表着当前键值对的键,当当前这一个键值对处理完之后,这个键在后面就不会被使用到了,就再把它从列表中移除

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	

Scanner scan=new Scanner(System.in);
int	n=scan.nextInt();
int	m=scan.nextInt();
scan.nextLine();
	StringBuilder sb=new StringBuilder();
	String input;
	/**
	因为题目中说了字符串中的内容不包含空格,则删掉空格不会影响键值字符串内容,所以为了格式清晰,就把所有的空格删掉,然后把所有内容整成一行
*/
	for(int i=0;i<n;i++) {
		input=scan.nextLine();
		input=input.replaceAll(" ", ""); //删掉所有空格
		sb.append(input);//整成一行
	}
	//用一个列表的最后一个元素来存当前的键字符串
	ArrayList<String> list =new ArrayList<>();
	list.add(null);//这样是为了第一层的键好处理
	HashMap<String, String> map=new HashMap<>();
	//用一个map来存所有的键值对,即使多层嵌套的对象也可以
char c;
String pre;
String key;
String value;
String tmp="";
//逐个字符遍历内容
	for(int i=1;i<sb.length();i++) {
		c=sb.charAt(i);
		switch (c) {
		case '}': //说明这个对象终止了,这个对象的键也就不会再用到了,所以移出
		               list.remove(list.size()-1);
			break;

		case '{': //说明当前这个键它的值是一个对象,所以把它这样子存进map以方便查找
	           key=list.get(list.size()-1);
	           map.put(key, "OBJECT");
   break;
		case '"': //说明这是一个字符串的开始,可能是键,也可能是值
                i++;//跳过双引号到它真正的内容开头
                tmp="";//这步很重要,先清空之前的临时字符串,不然之前的内容会重叠进来
                while(sb.charAt(i)!='"') {//一直处理到字符串结束
                	if(sb.charAt(i)=='\\') ++i;  //这一步很巧妙,若是第一个\就跳过它到下一个字符,这样可以非常巧妙地处理了\\和\"的情况
                	tmp+=sb.charAt(i++);//把这个字符加入临时字符串,然后到下一个字符
                }
                //字符串处理完了,要判断它是键还是值,
                if(sb.charAt(i+1)==':') {//如果它的下一位是:,那它就是键,
                	key=tmp;
                	pre=list.get(list.size()-1);
                	if(pre!=null)//还要看它是不是在第一层
                		list.add(pre+"."+key); //如果不是在第一层,就要把在前面接上之前键和.作为嵌套形式的键
                	else
                		list.add(key);//如果在第一层就不需要接嵌套的,就直接放入list
                }else {//如果是值,就将它与当前的键结合存入map,而且这样之后它的键也就不会再在后面被使用到了,所以移除,不然会占着茅坑会出错
                	value=tmp;
                	key=list.remove(list.size()-1);
                	map.put(key, value);
                	
                }
break;
		
		}
	}
	
	
//从map中查找,输出:

	String[] output=new String[m];
	for(int i=0;i<m;i++) {
		key=scan.nextLine();
		
		//如果map中包含该键,则只有两种可能,要么是object,要么是string:
		if(map.containsKey(key)) {
			if(map.get(key).equals("OBJECT"))
				output[i]="OBJECT";
			else
				output[i]="STRING "+map.get(key);
		}else  //如果map中没有该键,则不存在:
			output[i]="NOTEXIST";
	}
	for(String s:output)
		System.out.println(s);
}
}

猜你喜欢

转载自blog.csdn.net/qq_36276117/article/details/84547462