元素选择器

题意

在这里插入图片描述

思路

1、读入:用一个结构体存储其等级、lable、和id。
其中等级可以用前面的…个数/2来判断。
2、操作处理:
对于遍历到每个查询命令,依次解析出其重叠命令。
然后从后往依次匹配,找到则记录即可。

代码

#include<iostream>
#include <string>
#include <vector>
using namespace std;
const int N=107;


vector<string> qus;//保存查询
vector<int> ans;//保存答案

struct node
{
	string lable,id;
	int cnt;
}a[N];
void tosmall(string &s)
{
	for(int i=0;i<s.length();i++)
	{
		if(s[i]>='A'&&s[i]<='Z')
		{
			s[i]=s[i]+32;
		}
	}
}
bool isMatch(int x)
{  //向上一级查找
    int t=a[x].cnt,q=qus.size()-2;   //t当前级 q为查找到的级别
    for(int j=x-1;j>=0;j--)
    { //向上
        if(a[j].cnt==t-1)
        {//满足父亲
            if(qus[q][0]!='#'&&qus[q]==a[j].lable)
                q--;   //标签配对
            else if(qus[q][0]=='#'&&qus[q]==a[j].id)
                q--;     //id配对
            t=a[j].cnt;   //更新级别
            if(q<0) return true;    //所有级别都满足
        }
    }
    return false;
}
int main()
{
	int n,m,p1,p2,cnt,index;
	string s,tmp;
	cin>>n>>m;
	getchar();//吸收换行符 
	for(int i=1;i<=n;i++)
	{
		p1=-1;p2=-1;//p1-index p2-id; 
		cnt=0;
		getline(cin,s);
		for(int j=0;j<s.length();j++)
		{
			if(s[j]=='.')cnt++;
			else if(p1==-1&&s[j]!='#')p1=j;
			else if(s[j]=='#')p2=j; 
		}
		a[i].cnt=cnt/2;
		if(p2==-1)
		{
			a[i].lable=s.substr(p1);
			a[i].id="";
		}
		else
		{
			a[i].lable=s.substr(p1,p2-p1-1);
			a[i].id=s.substr(p2);
		}
		tosmall(a[i].lable);//标签小写 
	}
	
	for(int i=1;i<=m;i++)
	{
		ans.clear();
		qus.clear();
		getline(cin,s);
		for(int j=0;j<s.length();)
		{
			index=j;
			while(++index<s.length()&&s[index]!=' ');
			tmp=s.substr(j,index-j);
			if(tmp[0]!='#')tosmall(tmp);
			qus.push_back(tmp);
			j=index+1;
		 } 
		 int size=qus.size();
		 for(int j=1;j<=n;j++)
		{
		    if(qus[size-1][0]=='#'&&qus[size-1]==a[j].id||qus[size-1][0]!='#'&&qus[size-1]==a[j].lable)
            {  
                if(size==1) ans.push_back(j);   //一层 所有满足的
                else if(isMatch(j)) ans.push_back(j);  //多层  进入函数判断父级
        	}
		}
		        cout<<ans.size();
        for(int j=0;j<ans.size();j++)
        {
            cout<<" "<<ans[j];   //输出
        }
        cout<<endl;
	}
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值