试题编号: 201809-3
试题名称: 元素选择器
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
def Level(String):#此函数将实现存储html文档每一行的内容;并且以字典的形式返回缩进层级,标签和ID
for i in range(len(String)):
if String[i] != '.':#统计表示缩进的符号
break
level = i // 2#计算当前缩进
label = ''#存储标签
ID = ''#存储ID
if len(String[i:].split()) == 1:#只有一个选择器
label = String[i:]#写入
else:#后代迭选择器
label, ID = String[i:].split()#写入
return {'level': level,'label': label, 'id': ID}
row, test = map(int, input().split())#输入html总行号和测试数量
html = [None] # 存放html文档全部内容,位序表示行号;由于从一开始,列表位序从0开始所以,0号位用None占位html[]内的元素表示{'level': level,'label': label, 'id': ID}
#print(html)
for i in range(row):#输入
html.append(Level(input()))#直接进入函数判断,注意返回的是字典
search = []#存放查询的操作
for i in range(test):
search.append(list(input().split()))#存放到对应列表
def LabelOrId(String):#判断是哪种选择器,ID还是标签
temp = [0]#设置选择器个数初始值
for i in range(1, len(html)):#遍历整个html文件的结构
if String.lower() == html[i]['label'].lower() or String == html[i]['id']:#判断查询的标签是否在输入的html文档中;如果存在
temp[0] += 1#temp[0]表示有几个选择器(IDorLabel)temp[1]表示行号;也就是temp[]存储的是每一行选择器的个数
temp.append(i)
return temp
def ParentRow(row):#利用缩进关系确定html文档的父子关系
if row == 0:#html文档没内容
return 0
else:#有内容
level = html[row]['level']#返回html文档最高缩进层数
for i in range(row, 0, -1): # html第0位为None
if html[i]['level'] == level - 1:#只相差一层则存在父节点;注意存在爷爷父亲儿子的情况(三级或更多)
return i#返回父节点行号
return 0 # 不存在父节点
def Descendant(List):#后迭代选择器;参数是search[]
row = []#存放合法的,满足条件的行数、行号(输出的内容)
temp_answer = LabelOrId(List[-1])#前面都是相同的ID选择器或者元素选择器;返回的是最后一个选择器的行号
for i in range(temp_answer[0]):#遍历html文档
flag = []#利用此列表判断合法性
son_row = temp_answer[i + 1]#返回子节点行号;
family_row = [son_row]#把最小层级子节点行号存入family_row[]
while True:
parent_row = ParentRow(son_row)#返回存在子节点的行号
if parent_row == 0:#没有子节点
break
else:
family_row.append(parent_row)#把存在子节点的行号存入family_row[]
son_row = parent_row#更新子节点行号
family_row.reverse()#翻转;此时family_row[]的元素是从小到大的子节点行号
j, k = 0, 0#j记录查询个数,k记录子节点个数
while k < len(family_row):
if List[j].lower() == html[family_row[k]]['label'].lower() or List[j] == html[family_row[k]]['id']:#判断输入合法性
flag.append(True)
k += 1
j += 1
if j >= len(List):
break
else:
k += 1
if flag == [True] * len(List):#全部合法
row.append(temp_answer[i + 1])#返回子节点的行号
l = len(row)
row.insert(0, l)#等价于row[0]记录row的长度
return row
result = []
for i in range(test):
if len(search[i]) == 1:#长度为一不存在迭代
answer = LabelOrId(search[i][0]) # 标签和ID选择器
result.append(answer)
else:#迭代
answer = Descendant(search[i]) # 后代选择器
result.append(answer)
for i in range(len(result)):#按照格式输出
print(' '.join(map(str, result[i])))
# 测试样例
'''
11 5
html
..head
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #one
......div
........p #two
p
#subtitle
h3
div p
div div p
'''