1. 程式人生 > >CCF 201809-3 2018年9月第三題元素選擇器(python 100分題解)

CCF 201809-3 2018年9月第三題元素選擇器(python 100分題解)

問題描述

試題編號: 3
試題名稱: 元素選擇器
時間限制: 10.0s
記憶體限制: 512.0MB
問題描述:




提交後100分程式碼:

注意標籤選擇器大小寫不敏感,匹配時都轉成小寫,id選擇器大小寫敏感直接匹配

#元素選擇器
#輸入
n,m=map(int,input().split())
doc = []
sel = []
#結構化文件內容
for i in range(n):
    doc.append(input())
#帶查詢的選擇器
for i in range(m):
    sel.append(input())

#解析文件結構
cons = []
for i in range(n):
    level = doc[i].count('.')//2
    tag = ""
    tid = ""
    if(len(doc[i].split())==1):
        tag = doc[i][level*2:]
    else:
        left,right = doc[i].split()
        tag = left[level*2:]#標籤大小寫不敏感
        tid = right#id大小寫敏感
    pline = -1;
    for j in range(i-1,0-1,-1):
        if(cons[j]["level"]==level-1):
            pline = j+1;
            break;
    cons.append({"tag":tag,"id":tid,"level":level,"pline":pline})#將資訊存為字典新增到列表中

#元素選擇器選擇
collection=[]#結果儲存列表
for i in range(m):
    collection.append([])
    if(len(sel[i].split())==1):#選擇器不含空格
        if(sel[i][0]!='#'):#標籤選擇器
            for j in range(n):
                if(cons[j]["tag"].lower() == sel[i].lower()):#標籤大小寫不敏感
                    collection[i].append(j+1)   
        else:#id選擇器
            for j in range(n):
                if(cons[j]["id"] == sel[i]):#id大小寫敏感
                    collection[i].append(j+1)
    else:#後代選擇器
        
        p = sel[i].split()
        for j in range(n):
            parent = j+1
            k=len(p)-1
            while k>=0:#從後向前迭代檢查是否匹配
                match =False
                if(p[k][0]!='#'):
                    if(cons[parent-1]["tag"].lower() == p[k].lower()):
                        match = True
                    else:
                        if(parent == j+1 and k==len(p)-1):#第一次必須匹配上不然直接退出
                            break
                else:
                    if(cons[parent-1]["id"] == p[k]):
                        match = True
                    else:
                        if(parent == j+1 and k==len(p)-1):
                            break
                if(match):
                    k-=1
                    if(k<0):#匹配成功
                        collection[i].append(j+1)
                        break
                if(cons[parent-1]["pline"]==-1):#沒有父節點了仍未匹配成功即匹配失敗
                    break#匹配失敗退出
                parent = cons[parent-1]["pline"]#取父節點繼續檢查匹配
                
#輸出
for x in collection:    
    print(len(x)," ".join(map(str,x)))