1. 程式人生 > >CCF 201709 第三題JSON查詢 java(100分)

CCF 201709 第三題JSON查詢 java(100分)

自從會了正則表示式後,什麼都要用,這個題用正則反倒麻煩了。使用正則時,我卡在了多層物件的正則式上,因為百分之80的測試資料只有兩層結構,我就只得了八十分。

其實只要遍歷json的每一個字元,使用hashmap來儲存鍵和值,再加上棧來判斷當前的鍵值時屬於哪個物件就可以了。

一下程式碼得分100,耗時187ms

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] fistLine = scanner.nextLine().split(" ");
        int n = Integer.parseInt(fistLine[0]);
        int m = Integer.parseInt(fistLine[1]);

        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < n; i++) {
            stringBuffer.append(scanner.nextLine());
        }

        List<String> queries = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            queries.add(scanner.nextLine());
        }
        scanner.close();

        String json = stringBuffer.toString();

        HashMap<String, Object> hashMap = putValues(json);

        for(String query : queries){
            System.out.println(getValue(hashMap, query));
        }

    }

    private static Stack<HashMap<String, Object>> mapStack = new Stack<>();
    private static Stack<String> keyStack = new Stack<>();

    private static HashMap<String, Object> putValues(String json) {

        StringBuffer stringBuffer = new StringBuffer();
        int quoteCount = 0;

        HashMap<String, Object> currMap = null;
        HashMap<String, Object> rootMap = new HashMap<>();

        int i = 0;
        while (i < json.length()) {
            if(currMap == null){
                if(mapStack.isEmpty()){
                    currMap = rootMap;
                } else{
                    currMap = mapStack.pop();
                }
            }


            char c = json.charAt(i);
            switch (c) {
                case '\\':
                    stringBuffer.append(json.charAt(++i));
                    break;
                case ' ':
                case ',':
                case ':':
                    break;
                case '{': {
                    quoteCount = 0;
                    if (!keyStack.isEmpty()) {
                        HashMap<String, Object> hashMap = new HashMap<>();
                        String key = keyStack.pop();
                        currMap.put(key, hashMap);
                        currMap = hashMap;
                        mapStack.push(hashMap);
                    }
                }
                break;
                case '}':
                    if(!mapStack.isEmpty())
                        mapStack.pop();
                    currMap = null;
                    break;
                case '"': {
                    quoteCount++;
                    if (quoteCount % 4 == 0) {
                        String key = keyStack.pop();
                        String value = stringBuffer.toString();
                        currMap.put(key, value);
                    } else if (quoteCount % 4 == 2) {
                        String key = stringBuffer.toString();
                        keyStack.push(key);
                    }
                    stringBuffer.delete(0, stringBuffer.length());
                }
                break;
                default:
                    stringBuffer.append(c);
            }
            i++;
        }

        return rootMap;

    }

    private static String getValue(HashMap<String, Object> hashMap, String query) {
        if (query.contains(".")) {
            int index = query.indexOf(".");
            String key = query.substring(0, index);
            Object object = hashMap.get(key);
            if (object != null && !(object instanceof String)) {
                return getValue((HashMap<String, Object>) object, query.substring(index + 1));
            } else {
                return "NOTEXIST";
            }
        } else {
            Object object = hashMap.get(query);
            if (object != null) {
                if (object instanceof String)
                    return "STRING " + object.toString().replace("\\\\", "\\").replace("\\\"", "\"");
                return "OBJECT";
            } else {
                return "NOTEXIST";
            }
        }
    }
}