201809-3 元素选择器

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解题思路

先将结构化文档建成一棵树,如例题则建成:
在这里插入图片描述
一个树的node包含了

  • 标签
  • id
  • 所有孩子结点
  • 它的父亲结点

根据缩进数量判断深度,然后在指定位置进行结点插入即可

然后搜索其实就是个深搜

一开始卡在50过不去……发现题目理解有问题,比如说寻找div,其实只要找到div所在行就行,但是我连着叶子节点一起输出了hhhhh
而且题目中后代选择器可以既包含标签又包含id……

import java.util.*;

class treeNode{
	int lineNum;
	String label;
	String id;
	List<treeNode> children;
	treeNode parent;
	
	treeNode(int n, String l){
		lineNum = n;
		label = l.toLowerCase();
		children = new ArrayList<>();
		id = "";
	}
	void setID(String i) {
		id = i;
	}
	void setPar(treeNode p) {
		parent = p;
	}
	
	void addChild(treeNode t) {
		children.add(t);
	}
	List<treeNode> getAllChildren() {
		return children;
	}
	treeNode getnthChild(int n) {
		return children.get(n);
	}
	treeNode getParent() {
		return parent;
	}
}

public class Main {
	static List<treeNode> findByLabel(treeNode root, String label){
		if(root == null)
			return null;
		List<treeNode> answer = new ArrayList<>();
		treeNode nowNode = root;
		List<treeNode> children = root.getAllChildren();
		List<List<treeNode>> answers = new ArrayList<>();
		if(root.label.equals(label))
			answer.add(root);
		for(treeNode child: children)
			answers.add(findByLabel(child, label));
		for(int i = 0; i < answers.size(); i++) {
			answer.addAll(answers.get(i));
		}
		return answer;
	}
	
	static treeNode findByID(treeNode root, String id) {
		if(root == null)
			return null;
		List<treeNode> answers = new ArrayList<>();
		List<treeNode> children = root.getAllChildren();
		if(root.id.equals(id))
			return root;
		if(children.isEmpty())
			return null;
		for(treeNode child :children) 
			answers.add(findByID(child, id));
		int i;
		for(i = 0; i < answers.size(); i++) {
			if(answers.get(i) != null)
				return answers.get(i);
		}
		return null;
	}
	
	static List<Integer> getLineNum(treeNode root){
		if(root == null)
			return null;
		List<treeNode> children = root.getAllChildren();
		List<Integer> answer = new ArrayList<>();
		answer.add(root.lineNum);
		for(treeNode child: children) {
			answer.addAll(getLineNum(child));
		}
		return answer;
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String order = sc.nextLine();
		String temp[] = order.split(" ");
		int htmlNum = Integer.parseInt(temp[0]);
		int cssNum = Integer.parseInt(temp[1]);
		int i;
		order = sc.nextLine();
		String html[] = order.split(" ");
		treeNode root = new treeNode(1, html[0]);
		if(html.length > 1)
			root.setID(html[1]);
		int nowDepth = 0;
		treeNode nowNode = root;
		for(i = 2; i < htmlNum + 1; i++) {
			order = sc.nextLine();
			String h[] = order.split(" ");
			String first = h[0];
			int depth = 0;
			while(first.length() >= 2 && first.charAt(0) == '.' && first.charAt(1) == '.') {
				depth ++;
				first = first.substring(2);
			}
			if(depth > nowDepth) {
				treeNode t = new treeNode(i, first);
				if(h.length == 2)
					t.setID(h[1]);
				t.setPar(nowNode);
				nowNode.addChild(t);
				nowNode = t;
			}
			else if(depth == nowDepth) {
				treeNode t = new treeNode(i, first);
				if(h.length == 2)
					t.setID(h[1]);
				nowNode = nowNode.getParent();
				t.setPar(nowNode);
				nowNode.addChild(t);
				nowNode = t;
			}
			else {
				treeNode t = new treeNode(i, first);
				if(h.length == 2)
					t.setID(h[1]);
				for(int j = 0; j < nowDepth - depth + 1; j++)
					nowNode = nowNode.getParent();
				t.setPar(nowNode);
				nowNode.addChild(t);
				nowNode = t;
			}
			nowDepth = depth;
		}
		//建树↑
		
		for(i = 0; i < cssNum; i++) {
			order = sc.nextLine();
			String cons[] = order.split(" ");
			List<treeNode> answer = new ArrayList<>();
			if(cons[0].charAt(0) == '#')
				answer.add(findByID(root, cons[0]));
			else
				answer.addAll(findByLabel(root, cons[0].toLowerCase()));
			for(int j = 1; j < cons.length; j++) {
				List<treeNode> pre = new ArrayList<>();
				if(cons[j].charAt(0) == '#') {
					for(treeNode t: answer) {
						if(t != null)
							for(treeNode t1: t.getAllChildren())
								pre.add(findByID(t1, cons[j]));
					}
					answer = new ArrayList<treeNode>(Arrays.asList(new treeNode[pre.size()]));
					Collections.copy(answer, pre);
				}
				else {
					for(treeNode t: answer) {
						if(t != null)
							for(treeNode t1: t.getAllChildren())
								pre.addAll(findByLabel(t1, cons[j]));
					}
					answer = new ArrayList<treeNode>(Arrays.asList(new treeNode[pre.size()]));
					Collections.copy(answer, pre);
				}
			}
			List<Integer> outPut = new ArrayList<>();
			for(treeNode NowNode: answer) {
				if(NowNode == null)
					continue;
				else
					outPut.add(NowNode.lineNum);
			}
			outPut = new ArrayList<Integer>(new LinkedHashSet<Integer>(outPut));
			System.out.print(outPut.size());
			for(int j = 0; j < outPut.size(); j++) 
				System.out.print(" " + outPut.get(j));
			System.out.println();
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值