元素选择器 201809-3 C++

该程序读取n行输入,每行包含一个文档元素的标签和ID,存储在G中。接着处理m个选择器,通过find函数递归查找匹配元素,结果存储在setS中并输出其大小和内容。find函数检查当前深度和字符串序列,若找到匹配项则继续查询下一深度。示例中展示了不同选择器的查询结果。
摘要由CSDN通过智能技术生成


一、题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

原题目链接

二、解题

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.解释

  1. find()函数

find() 函数是一个递归函数,用于查询给定的字符串序列,并将结果存储在一个 set 中。

传入参数的含义如下:

vi:当前查询的字符串在 v 中的索引。
dp:当前查询的深度。
s:存储查询到的结果。
v:要查询的标签和 ID 的字符串序列。
N:要查询的字符串序列中最后一个字符串的索引。
函数首先检查当前深度是否大于最大深度或者是否已经查询结束。如果是,则返回。然后,它检查在当前深度是否能够查询到第 vi 个字符串。如果能够查询到,则判断是否已经查询结束。如果是,则将结果存储在 set 中;否则,继续递归调用 find 函数来查询下一深度的下一个字符串。最后,不管如何都要继续递归调用 find 函数来查询下一深度。

  1. 运行过程,以题目所给的例子为例

这个程序使用给定输入的模拟运行过程:

程序开始运行,读取两个整数 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}。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值