• [csp-201809-3]元素选择器-编译原理


    声明:同样是参考照抄hyh学长的代码!(有问题我马上删这篇emm

    题目链接:http://118.190.20.162/view.page?gpid=T77

    题面:

    这棵树的样子(同样是来自学长的图) 

     

    题解:

    要解决的两个关键问题:

    第一个是语义解析,也就是把树构造出来。这个也是用指针实现。这个树的构建比起上一题来更简单,因为节点实际上都是一样的,而上一题(JSON查询)则要分为对象和字符串两种。

      这里要注意parent的指向,用一个堆实现查找parent。

    第二个是查询。要查询符合条件的路径。这里稍微需要一些思路。

      如果直接从上往下找,那这个复杂度最坏的情况是n^2的。但是在实际情况中(也是题目给的提示),从后往前找会大大减少情况(可以排除很多情况)。

    处理细节很重要呀!同样也要想清楚每个函数的作用!

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 struct tree
      5 {
      6     int id, dots;
      7     string tag, name;
      8     tree* parent;
      9     
     10     tree(int id, int dots, string tag, string name): id(id), dots(dots), tag(tag), name(name) ,parent(0) {}//parent的初始化
     11 };
     12 
     13 void split(const string &str, vector<string> &out)
     14 {
     15     string last;
     16     last.clear();
     17     for (int i = 0; i < str.size(); i++)
     18     {
     19         if(str[i] == ' ') 
     20         {
     21             out.push_back(last);
     22             last.clear();
     23         }
     24         else last+=str[i];
     25     }
     26     out.push_back(last);
     27 }
     28 
     29 bool equal_ignore_case(const string &a,const string &b)
     30 {
     31     if(a.size() != b.size()) return 0;
     32     for(int i = 0; i < a.size(); i++)
     33     {
     34         if(tolower(a[i]) != tolower(b[i])) return 0;
     35     }
     36     return 1;
     37 }
     38 
     39 bool apply(string str, tree *t)
     40 {
     41     if(str[0] == '#') return str == t->name;
     42     else return equal_ignore_case(str, t->tag);
     43 }
     44 
     45 int main()
     46 {
     47     // freopen("a.in","r",stdin);
     48     int n,m;
     49     string line;
     50     scanf("%d%d",&n,&m);
     51     
     52     getline(cin,line);
     53     
     54     vector<tree *> nodes;
     55     stack<tree *> sta;
     56     
     57     for(int i = 1; i <= n; i++)
     58     {
     59         getline(cin, line);
     60         
     61         int dots=0;
     62         while (line[dots] == '.') dots++;
     63         
     64         string tag, name;
     65         stringstream ss(line.substr(dots));
     66         ss >> tag >> name;
     67         
     68         tree *now = new tree(i, dots, tag, name);
     69         if(!sta.empty())
     70         {
     71             tree* top;
     72             while (top = sta.top(), top->dots >= dots) 
     73                 sta.pop();
     74             now->parent = top;
     75         }
     76         sta.push(now);
     77         nodes.push_back(now);
     78     }
     79     /*
     80     for(int i = 0; i < nodes.size(); i++)
     81     {
     82         printf("id = %d  dots = %d ",nodes[i]->id,nodes[i]->dots);
     83         cout << "tag = " << nodes[i]->tag << " name = " << nodes[i]->name ;
     84         if(nodes[i]->parent) cout << " parent = " << nodes[i]->parent->id << endl;
     85         else cout << endl;
     86     }
     87     */
     88     vector<string> selector;
     89     vector<int> ans;
     90     ans.clear();
     91     while (m--)
     92     {
     93         getline(cin, line);
     94         selector.clear();
     95         split(line, selector);
     96         // printf("************* m = %d
    ",m);
     97         // for(int i = 0 ; i < selector.size(); i++) 
     98             // cout << selector[i] << endl;
     99         ans.clear();
    100         for (int i = 0; i < nodes.size(); i++)
    101         {
    102             if (apply(selector.back(),nodes[i]))
    103             {
    104                 tree *t = nodes[i];
    105                 int sl = selector.size()-1;
    106                 while(t && sl>=0)
    107                 {
    108                     if(apply(selector[sl],t)) sl--;
    109                     t = t->parent;
    110 
    111                 }
    112                 if (sl == -1) 
    113                     ans.push_back(nodes[i]->id);
    114             }
    115         }
    116         printf("%d ",ans.size()); 
    117         for (int i = 0; i < ans.size() ; i++)
    118             printf("%d ",ans[i]);
    119         printf("
    ");
    120     }
    121     
    122     return 0;
    123 }

     更新一下代码(刷题的时候又遇到了这题,重新做了一遍(并没有什么区别..写码习惯不同))

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 struct tree{
      5     string tag,name;
      6     int dots;
      7     tree* parent;
      8     
      9     tree(int dots, string tag, string name): dots(dots),tag(tag),name(name),parent(0) {}
     10 };
     11 
     12 bool check(const string &s,tree* t)
     13 {
     14     if(s[0]=='#') return s == t->name;
     15     else 
     16     {
     17         if(s.size()!=t->tag.size()) return 0;
     18         for(int i=0;i<s.size();i++)
     19         {
     20             if(tolower(s[i])!=tolower(t->tag[i])) return 0;
     21         }
     22         return 1;
     23     }
     24 }
     25 
     26 void divide(const string &s,vector<string> &vec)
     27 {
     28     string token;
     29     token.clear();
     30     vec.clear();
     31     for(int i=0;i<s.size();i++)
     32     {
     33         if(s[i]==' ') 
     34         {
     35             vec.push_back(token);
     36             token.clear();
     37         }
     38         else token+=s[i];
     39     }
     40     vec.push_back(token);
     41 }
     42 
     43 int main()
     44 {
     45     //freopen("a.in","r",stdin);
     46     int n,m;
     47     scanf("%d%d",&n,&m);
     48     string line;
     49     getline(cin,line);
     50     
     51     vector<tree* > nodes;
     52     nodes.clear();
     53     stack<tree* > sta;
     54     while(!sta.empty()) sta.pop();
     55     
     56     for(int i=1;i<=n;i++)
     57     {
     58         getline(cin,line);
     59         
     60         int dots=0;
     61         while(line[dots]=='.') dots++;
     62         
     63         string tag,name;
     64         stringstream ss(line.substr(dots));
     65         ss >> tag >> name;
     66         
     67         tree* now = new tree(dots, tag, name);
     68         
     69         if(!sta.empty())
     70         {
     71             tree* top;
     72             while( top = sta.top() , top->dots >= dots ) 
     73                 sta.pop();  
     74             now->parent = top;
     75         }
     76         sta.push(now);
     77         nodes.push_back(now);
     78     }
     79     
     80     // for(int i=0;i<nodes.size();i++)
     81     // {
     82         // cout << "id = " << i << " tag = " << nodes[i]->tag << " name = " << nodes[i]->name ;
     83         // if(nodes[i]->parent) cout<< " parent = " << nodes[i]->parent->tag;
     84         // cout << endl;
     85     // }
     86         
     87     vector<string> sel;
     88     vector<int> ans;
     89     
     90     while(m--)
     91     {
     92         getline(cin,line);
     93         divide(line,sel);
     94         
     95         ans.clear();
     96         
     97         for(int i=0;i<nodes.size();i++)
     98         {
     99             int sl=sel.size()-1;
    100             if(check(sel[sl],nodes[i])) 
    101             {
    102                 tree* t=nodes[i]->parent;
    103                 sl--;
    104                 while(t && sl>=0)
    105                 {
    106                     if(check(sel[sl],t)) sl--;
    107                     t=t->parent;
    108                 }
    109                 if(sl==-1) ans.push_back(i+1);
    110             }
    111         }
    112         printf("%d ",ans.size());
    113         for(int i=0;i<ans.size();i++) printf("%d ",ans[i]);printf("
    ");
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    中国科学技术大学2021年数学分析考研试卷
    中国科学技术大学2021年高等代数考研试卷
    中国海洋大学2021年数学分析考研试卷
    中国海洋大学2021年高等代数考研试卷
    中北大学2021年高等代数考研试卷
    数学分析教程第3版参考解答1.6自然对数的底
    数学分析中的问题与方法参考解答第1章极限论
    郑州大学2021年数学分析考研试卷
    郑州大学2021年高等代数考研试卷
    浙江师范大学2021年高等代数考研试卷
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/9999194.html
Copyright © 2020-2023  润新知