201809-3元素选择器

Posted mopa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了201809-3元素选择器相关的知识,希望对你有一定的参考价值。

技术图片

技术图片

技术图片

技术图片

思路

首先建立结构体,将结构化文档存储起来,并记录节点的父节点索引。

struct css {
	string name;
	int parent;
	string id;
	css() {}
	css(string name,int parent,string id) {
		this->name = name;
		this->parent = parent;
		this->id = id;
	}
};

然后对读入的文档进行处理,首先是小数点的读取,由于两个小数点代表一级,所以首先需要记录当前节点的级数,如果与上一个节点的级数相同,则证明二者是兄弟关系,其父节点相同,若级数比上个节点多,则父节点为上个节点,若比上个节点少,则父节点为其祖先节点,而对于当前节点的父节点,采用类似于路径解析的方法,使用栈来记录当前父节点索引。

具体实现如下

if(v.size()==0) {
			css p = css(tname,-1,tid);
			st.push(i);
			lastci = ci;
			v.push_back(p);
		} else {
			if(lastci == ci) {
				css p = css(tname,st.top(),tid);
				v.push_back(p);
			} else if(lastci > ci) {
				int num = lastci - ci;
				lastci = ci;
				while(num) {
					num--;
					st.pop();
				}
				css p = css(tname,st.top(),tid);
				v.push_back(p);
			} else if(lastci < ci) {
				lastci = ci;
				st.push(i-1);
				css p = css(tname,i-1,tid);
				v.push_back(p);
			}
		}

然后是对选择语句的处理,首先将其存放在一个vector中,然后从后向前遍历,找到满足根节点的ans,然后对ans遍历,找到满足其所有祖先条件的节点,得到最终的ans,遍历过程如下:

for(int j=0; j<ans.size(); j++) {
			int tans = v[ans[j]].parent;
			bool isOK = true;
			for(int k=name.size()-1; k>=0; k--) {
				tname = name[k];
//				cout<<tname<<endl;
				while(tans!=-1 && v[tans].name!=tname && v[tans].id!=tname) {
//					cout<<tans<<","<<v[tans].name<<","<<tname<<endl;
					tans = v[tans].parent;
				}
//				cout<<tans<<","<<","<<tname<<endl;
				if(tans==-1) {
					isOK = false;
					break;
				}
				tans = v[tans].parent;
			}
			if(isOK) amp.push_back(ans[j]);
		}

值得注意的是,题目提到对于文档的元素标签大小写不敏感,而对于id属性却是大小写敏感的,所以如果没有注意大小写的话只能拿90分,因此需要分别进行处理,将文档标签全部改为小写:

(tmp.c_str()[j]>=‘a‘||tmp.c_str()[j]<=‘9‘)?(tmp.c_str()[j]):(tmp.c_str()[j]-‘A‘+‘a‘)

注意对于数字是不需要更改的,如果没有<=‘9‘的条件只能拿40分。

全部代码

#include<iostream>
#include<vector>
#include<stack>
using namespace std;
struct css {
	string name;
	int parent;
	string id;
	css() {}
	css(string name,int parent,string id) {
		this->name = name;
		this->parent = parent;
		this->id = id;
	}
};
int main() {
	int n,m;
	cin>>n>>m;
	vector<css> v;
	stack<int> st;
	int cur = 0;
	string tmp;
	int lastci;
	getchar();
	for(int i=0; i<n; i++) {
		getline(cin,tmp);
		int ci = 0;
		string tname;
		string tid = "";
		for(int j=0; j<tmp.size(); j++) {
			if(tmp.c_str()[j]==‘.‘) ci++;
			else if(tmp.c_str()[j]==‘ ‘) {
				j++;
				while(j<tmp.size()) {
					tid.push_back(tmp.c_str()[j]);
					j++;
				}
				break;
			} else tname.push_back((tmp.c_str()[j]>=‘a‘||tmp.c_str()[j]<=‘9‘)?(tmp.c_str()[j]):(tmp.c_str()[j]-‘A‘+‘a‘));
		}
		ci = ci/2;
		if(v.size()==0) {
			css p = css(tname,-1,tid);
			st.push(i);
			lastci = ci;
			v.push_back(p);
		} else {
			if(lastci == ci) {
				css p = css(tname,st.top(),tid);
				v.push_back(p);
			} else if(lastci > ci) {
				int num = lastci - ci;
				lastci = ci;
				while(num) {
					num--;
					st.pop();
				}
				css p = css(tname,st.top(),tid);
				v.push_back(p);
			} else if(lastci < ci) {
				lastci = ci;
				st.push(i-1);
				css p = css(tname,i-1,tid);
				v.push_back(p);
			}
		}
	}
//	cout<<v.size()<<endl;
//	for(int i=0;i<v.size();i++)
//		cout<<v[i].id<<","<<endl;
	for(int i=0; i<m; i++) {
		getline(cin,tmp);
		int ci = 0;
		vector<string> name;
		vector<int> ans;
		string tname;
		int cur = 0;
		for(int j=0; j<tmp.size(); j++) {
			tname = "";
			bool fir = true;
			bool id = false;
			while(tmp.c_str()[j]!=‘ ‘&&j<tmp.size()) {
				if(fir) {
					if(tmp.c_str()[j]==‘#‘) id = true;
					fir = false;
				}
				if(!id)
					tname.push_back((tmp.c_str()[j]>=‘a‘||tmp.c_str()[j]<=‘9‘)?(tmp.c_str()[j]):(tmp.c_str()[j]-‘A‘+‘a‘));
				else tname.push_back(tmp.c_str()[j]);
				j++;
			}
//			cout<<tname<<endl;
			name.push_back(tname);
		}
		tname = name[name.size()-1];
//		cout<<tname<<endl;
		for(int j=0; j<v.size(); j++) {
			if(v[j].name==tname || v[j].id == tname) {
//				cout<<tname<<":" <<v[j].name<<endl;
				ans.push_back(j);
			}
		}
		name.pop_back();
		vector<int> amp;
		for(int j=0; j<ans.size(); j++) {
			int tans = v[ans[j]].parent;
			bool isOK = true;
			for(int k=name.size()-1; k>=0; k--) {
				tname = name[k];
//				cout<<tname<<endl;
				while(tans!=-1 && v[tans].name!=tname && v[tans].id!=tname) {
//					cout<<tans<<","<<v[tans].name<<","<<tname<<endl;
					tans = v[tans].parent;
				}
//				cout<<tans<<","<<","<<tname<<endl;
				if(tans==-1) {
					isOK = false;
					break;
				}
				tans = v[tans].parent;
			}
			if(isOK) amp.push_back(ans[j]);
		}
		ans = amp;
		cout<<ans.size();
		for(int j=0; j<ans.size(); j++) {
			cout<<" "<<ans[j]+1;
		}
		cout<<endl;
	}
	return 0;
}

以上是关于201809-3元素选择器的主要内容,如果未能解决你的问题,请参考以下文章

CCF201809-3 元素选择器(100分)文本处理

201809-3元素选择器

CCF(元素选择器:50分):字符串+模拟

jquery中的$的特殊用法

jQ选择器学习片段(JavaScript 部分对应)

VSCode自定义代码片段——CSS选择器