CSP 元素选择器

package csp.csp201809;

import java.util.*;


//notice 这道题的要点是要注意第一个节点 检查html节点能否正确输出
//查询的子元素可能不是相邻的,所有find方法找到一个之后还是要继续找下一个节点,70分的用例是不相邻的情况,要有注意输出节点的排序

public class 元素选择器 {
    public static Dom root = new Dom("");

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int htmlcount = Integer.parseInt(str.split(" ")[0]);
        int testcount = Integer.parseInt(str.split(" ")[1]);

        int nowlayer = 0;
        Dom now = null;
        for (int i = 0; i < htmlcount; i++) {
            String inputs = sc.nextLine();
            int layer = getLayer(inputs);
            inputs = inputs.replaceAll("\\.", "");
            Dom dom;
            if (inputs.contains("#")) {
                String[] string = inputs.split(" ");
                dom = new Dom(string[0].toLowerCase(), layer, string[1], i);
            } else {
                dom = new Dom(inputs.toLowerCase(), layer, i);
            }

            //判断节点层次
            if (layer == 0) {
                root.child.add(dom);
            } else if (layer > nowlayer) {
                now.child.add(dom);
                dom.father = now;
            } else if (layer < nowlayer) {
                getFather(now, dom).child.add(dom);
                dom.father = getFather(now, dom);
            } else if (layer == nowlayer) {
                dom.father = now.father;
                now.father.child.add(dom);
            }
            now = dom;
            nowlayer = layer;
        }


        //print(root);

        List<String> testList = new ArrayList<>();
        for (int i = 0; i < testcount; i++) {
            testList.add(sc.nextLine());
        }
        for (int i = 0; i < testcount; i++) {
            select(root, testList.get(i).split(" "));
        }
    }

    public static List<Integer> find(Dom dom, String condition, List<Integer> findlist) {
        if (condition.startsWith("#")) {
            if (dom.id != null && dom.id.equals(condition)) {
                findlist.add(dom.row);
            } else {
                for (Dom dom1 : dom.child) {
                    find(dom1, condition, findlist);
                }
            }
        } else {

        }
        return findlist;
    }

    //改进的搜索方式
    public static void select(Dom root, String[] conditionList) {
        List<Dom> domlist = new ArrayList<>();
        domlist.add(root);
//        System.out.println(Arrays.asList(conditionList));
//        System.out.println("the condition length is" + conditionList.length);

        for (int i = 0; i < conditionList.length; i++) {
            //我们把所有的查询到的节点都装了起来
            //它们之间可能不是一级的
            String condition = conditionList[i];
            List<Dom> findlist = new ArrayList<>();
            for (Dom dom : domlist) {
                for (Dom dom1 : dom.child) {
                    findlist.addAll(findDom(dom1, condition, new ArrayList<Dom>()));
                }
            }
//            for (Dom dom : findlist) {
//                printDom(dom);
//            }
            domlist = findlist;

            if (i == conditionList.length - 1) {
                findlist = tidy(findlist);
                //System.out.println("the search has ended");
                if (findlist.size() == 0) {
                    System.out.println(0);
                } else {
                    //output
                    System.out.print(findlist.size());
                    for (Dom dom : findlist) {
                        System.out.print(" " + (dom.row + 1));
                    }
                    System.out.println("");
                }
            }
        }
    }

    public static List<Dom> findDom(Dom dom, String condition, List<Dom> findlist) {
        if (condition.startsWith("#")) {
            if (dom.id != null && dom.id.equals(condition)) {
                findlist.add(dom);
            }
            //就算找到了还是要查找子节点
            for (Dom dom1 : dom.child) {
                findDom(dom1, condition, findlist);
            }

        } else {
            condition = condition.toLowerCase();
            if (dom != null && dom.type.equals(condition)) {
                findlist.add(dom);
            }
            //就算找到了还是要查找子节点
            for (Dom dom1 : dom.child) {
                findDom(dom1, condition, findlist);
            }


        }
        return findlist;
    }

    public static void print(Dom dom) {
        for (int i = 0; i < dom.layer; i++) {
            System.out.print(" ");
        }
        System.out.println(dom.type + dom.id);
        for (Dom dom1 : dom.child) {
            print(dom1);
        }
    }

    public static void printDom(Dom dom) {
        System.out.println("print dom" + dom.layer + " " + dom.type + " " + dom.id);
    }

    public static Dom getFather(Dom now, Dom newdom) {
        Dom father = now;
        while (newdom.layer >= father.layer) {
            father = father.father;
        }
        return father;
    }

    //集合去重并排序
    public static List<Dom> tidy(List<Dom> list) {
        List<Dom> newList = new ArrayList<>();
        for (Dom dom : list) {
            if (!newList.contains(dom)) {
                newList.add(dom);
            }
        }
        Collections.sort(newList, new Comparator<Dom>() {
            @Override
            public int compare(Dom o1, Dom o2) {
                if (o1.row < o2.row) {
                    return -1;
                } else if (o1.row > o2.row) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });
        return newList;
    }

    public static int getLayer(String str) {
        char[] c = str.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] != '.') {
                //System.out.println("layer"+i/2);
                return i / 2;
            }
        }
        return 0;
    }

    public static class Dom {
        int row;
        int layer;
        String type;
        String id;
        List<Dom> child = new ArrayList<>();
        Dom father;

        public Dom(String type) {
            this.type = type;
        }

        public Dom(String type, int layer, int row) {
            this.type = type;
            this.layer = layer;
            this.row = row;
        }

        public Dom(String type, int layer, String id, int row) {
            this.type = type;
            this.layer = layer;
            this.id = id;
            this.row = row;
        }
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值