一、题目
二、解题
1.题目
这个程序的运行流程如下:
- 程序开始运行,读取两个整数 n 和 m。
- 程序读取 n 行输入,每行输入表示文档中的一个元素。
- 对于每个元素,程序提取标签和 ID 并将其存储在 G 中。
- 程序读取 m 行输入,每行输入表示一个选择器。
- 对于每个选择器,程序执行 find 函数来查找匹配项。
- find 函数在 G 中查找匹配项,并将结果存储在一个 set 类型变量 S 中。
- 程序输出 S 的大小和内容。
- 程序结束。
2.代码
dev c++ 5.11
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cstring>
using namespace std;
typedef pair<string,int> P;
map<P,vector<int> > G;//存储<<标签或ID,深度>,存在的行>
map<P,vector<int> >::iterator it;
int max_dp,n,m;
void toLower(string& s){for(int i=0,ni=s.size();i<ni;++i)s[i]=tolower(s[i]);}
//查询在v中的第vi个字符串
void find(int vi,int dp,set<int>&s,const vector<string>&v,const int& N){
if(dp>max_dp||vi>N) return;//如果大于深度或者查询结束
if((it=G.find(P(v[vi],dp)))!=G.end()){//如果在dp深度查询到第vi个字符串
if(vi==N)
s.insert(it->second.begin(),it->second.end());//如果查询结束
else
find(vi+1,dp+2,s,v,N);//否则查询下一深度的下一个查询
}
find(vi,dp+2,s,v,N);//不管如何都要查询下一深度
}
int main(){
string s;
cin>>n>>m,cin.get(),max_dp=0;
for(int i=0,j,nj,l;i<n;++i){//处理文档
getline(cin,s),j=0,nj=s.size();
while(j<nj&&s[j]=='.')++j;
l=j;
while(j<nj&&s[j]!=' ')++j;
string label=s.substr(l,j-l);
max_dp=max(max_dp,l),toLower(label);
G[P(label,l)].emplace_back(i+1);//这是标签
while(j<nj&&s[j]==' ')++j;
if(j==nj)continue;
G[P(s.substr(j,nj-j),l)].emplace_back(i+1);//这是ID
}
for(int i=0;i<m;++i){//处理查询
getline(cin,s);
int j=0,nj=s.size(),l;
vector<string>V;//要查询的标签和ID
set<int>S;//存储查询到的结果
while(j<nj){//循环处理深度
l=j;
while(j<nj&&s[j]!=' ')++j;
string s1=s.substr(l,j-l);
if(s1[0]!='#')toLower(s1);//如果不是ID那么都处理成小写
V.emplace_back(s1);
while(j<nj&&s[j]==' ')++j;
}
// 查询并输出结果。
find(0, 0, S, V, V.size() - 1);
cout << S.size();
for (set<int>::iterator it = S.begin(); it != S.end(); ++it) cout << " " << (*it);
cout << endl;
}
return 0;
}
3.提交结果
总结
1.解释
find()
函数
find() 函数是一个递归函数,用于查询给定的字符串序列,并将结果存储在一个 set 中。
传入参数的含义如下:
vi:当前查询的字符串在 v 中的索引。
dp:当前查询的深度。
s:存储查询到的结果。
v:要查询的标签和 ID 的字符串序列。
N:要查询的字符串序列中最后一个字符串的索引。
函数首先检查当前深度是否大于最大深度或者是否已经查询结束。如果是,则返回。然后,它检查在当前深度是否能够查询到第 vi 个字符串。如果能够查询到,则判断是否已经查询结束。如果是,则将结果存储在 set 中;否则,继续递归调用 find 函数来查询下一深度的下一个字符串。最后,不管如何都要继续递归调用 find 函数来查询下一深度。
- 运行过程,以题目所给的例子为例
这个程序使用给定输入的模拟运行过程:
程序开始运行,读取两个整数 n = 11 和 m = 5。
程序读取 n = 11 行输入,每行输入表示文档中的一个元素。
对于每个元素,程序提取标签和 ID 并将其存储在 G 中。在这个例子中,G 的内容如下:
G = {
{("html", 0): [1]},
{("head", 2): [2]},
{("title", 4): [3]},
{("body", 2): [4]},
{("h1", 4): [5]},
{("p", 4): [6]},
{("#subtitle", 4): [6]},
{("div", 4): [7]},
{("#main", 4): [7]},
{("h2", 6): [8]},
{("p", 6): [9]},
{("#one", 6): [9]},
{("div", 6): [10]},
{("p",8) :[11]}
}
程序读取 m =5 行输入,每行输入表示一个选择器。
对于第一个选择器 “p”,程序执行 find 函数来查找匹配项。find 函数在 G 中查找匹配项,并将结果存储在一个 set 类型变量 S 中。对于这个选择器,S 的大小为 S.size()=3 ,内容为 S={6,9,11}。
对于第二个选择器 “#subtitle” ,程序执行 find 函数来查找匹配项。find 函数在 G 中查找匹配项,并将结果存储在一个 set 类型变量 S 中。对于这个选择器,S 的大小为 S.size()=1 ,内容为 S={6}。
对于第三个选择器 “h3” ,程序执行 find 函数来查找匹配项。find 函数在 G 中查找匹配项,并将结果存储在一个 set 类型变量 S 中。对于这个选择器,没有任何匹配项,所以 S 的大小为 S.size()=0 ,内容为空。
对于第四个选择器 “div p” ,程序执行 find 函数来查找匹配项。find 函数在 G 中查找匹配项,并将结果存储在一个 set 类型变量 S 中。对于这个选择器,S 的大小为 S.size()=2 ,内容为 S={9,11}。
对于第五个选择器 “div div p” ,程序执行 find 函数来查找匹配项。find 函数在 G 中查找匹配项,并将结果存储在一个 set 类型变量 S 中。对于这个选择器,S 的大小为 S.size()=1 ,内容为 S={11}。