CCF JSON查詢 Java 完美滿分 詳解
阿新 • • 發佈:2018-12-01
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); } }