去除字符串首尾的空白字符(包括空格、制表符、换行符和回车符)
void trim(string &s) {
size_t start = s.find_first_not_of(" \t\n\r");
size_t end = s.find_last_not_of(" \t\n\r");
if (start == string::npos) {
s = "";
} else {
s = s.substr(start, end - start + 1);
}
}
- 参数: string &s - 传入的字符串引用,函数会直接修改该字符串。
- 通过使用引用,你可以确保函数内部对字符串的修改直接影响到传入的原始字符串,而不是它的副本。这样可以避免额外的拷贝和内存分配。
- 在C++中,find_first_not_of 和 find_last_not_of 是 std::string 类的成员函数,用于查找字符串中第一个或最后一个不匹配指定字符集的字符的位置。
- 使用 find_first_not_of 方法找到字符串中第一个不是空格、制表符、换行符或回车符的字符位置。
- 如果 start 等于 string::npos,说明整个字符串都是空白字符,将字符串置为空字符串。
- 否则,使用 substr 方法提取从 start 到 end 之间的子字符串,并赋值给原字符串 s。
从格式化的属性字符串中提取键值对,并将其存储在一个向量中
vector<pair<string, string>> parse_attrs(const string &s) {
vector<pair<string, string>> attrs;
size_t pos = 0;
while (pos < s.size()) {
while (pos < s.size() && isspace(s[pos])) {
pos++;
}
if (pos >= s.size()) {
break;
}
size_t equal_pos = s.find('=', pos);
if (equal_pos == string::npos) {
break;
}
string attr_name = s.substr(pos, equal_pos - pos);
trim(attr_name);
pos = equal_pos + 1;
while (pos < s.size() && isspace(s[pos])) {
pos++;
}
if (pos >= s.size() || s[pos] != '"') {
break;
}
pos++;
size_t value_start = pos;
size_t value_end = s.find('"', pos);
if (value_end == string::npos) {
break;
}
string attr_value = s.substr(value_start, value_end - value_start);
pos = value_end + 1;
attrs.emplace_back(attr_name, attr_value);
}
return attrs;
}
- emplace_back: 这是 vector 类的一个成员函数,用于在容器的末尾直接构造元素。
main函数
int main() {
int N, Q;
cin >> N >> Q;
cin.ignore();
vector<string> tag_stack;
unordered_map<string, unordered_map<string, string>> attributes;
for (int i = 0; i < N; ++i) {
string line;
getline(cin, line);
if (line.empty()) continue;
if (line[1] == '/') {
if (!tag_stack.empty()) {
tag_stack.pop_back();
}
} else {
line = line.substr(1, line.size() - 2);
istringstream iss(line);
string tag_name;
iss >> tag_name;
string attr_str;
getline(iss >> ws, attr_str);
vector<pair<string, string>> attrs = parse_attrs(attr_str);
tag_stack.push_back(tag_name);
string current_path;
for (const string& tag : tag_stack) {
if (!current_path.empty()) {
current_path += ".";
}
current_path += tag;
}
for (const auto& attr : attrs) {
attributes[current_path][attr.first] = attr.second;
}
}
}
for (int i = 0; i < Q; ++i) {
string query;
getline(cin, query);
size_t tilde_pos = query.find('~');
if (tilde_pos == string::npos) {
cout << "Not Found!" << endl;
continue;
}
string path = query.substr(0, tilde_pos);
string attr = query.substr(tilde_pos + 1);
if (attributes.find(path) != attributes.end() && attributes[path].find(attr) != attributes[path].end()) {
cout << attributes[path][attr] << endl;
} else {
cout << "Not Found!" << endl;
}
}
return 0;
}
- unordered_map<string, unordered_map<string, string>> attributes; 是一个嵌套的哈希表(也称为字典或映射),用于存储HTML标签的属性。
- getline 函数从输入流 cin 中读取字符,直到遇到换行符(‘\n’),但不包括换行符。读取的字符被存储到字符串 line 中。
- attributes.find(path) 尝试在 attributes 中找到键为 path 的元素。
如果找到了这个路径,find 方法返回一个迭代器,指向找到的元素;否则,返回 attributes.end()。 - 然后,attributes[path].find(attr) 尝试在这个内部的 unordered_map 中找到键为 attr 的元素。
- 同样地,如果找到了这个属性,find 方法返回一个迭代器,指向找到的元素;否则,返回 attributes[path].end()。