先将结构化文档建成一棵树,如例题则建成:
一个树的node包含了
根据缩进数量判断深度,然后在指定位置进行结点插入即可
然后搜索其实就是个深搜
一开始卡在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();
}
}
}