1. 程式人生 > >CCF JSON查詢 Java 完美滿分 詳解

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