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;
}
}
}