In this HackerRank Attribute Parse problem in the c++ programming language you have This challenge works with a custom-designed markup language HRML. In HRML, each element consists of a starting and ending tag, and there are attributes associated with each tag. Only starting tags can have attributes. We can call an attribute by referencing the tag, followed by a tilde, ‘~’ and the name of the attribute. The tags may also be nested.
The opening tags follow the format:
<tag-name attribute1-name = “value1” attribute2-name = “value2” …>
The closing tags follow the format:
</tag-name>
The attributes are referenced as:
tag1~value
tag1.tag2~name
Given the source code in HRML format consisting of N lines, answer Q queries. For each query, print the value of the attribute specified. Print “Not Found!” if the attribute does not exist.
HackerRank Attribute Parser problem solution in c++. programming.
#include <iostream> #include <string> #include <map> #include <iomanip> #include <vector> #include <cmath> using namespace std; bool checkEnd(string name, string end) { name = "</" + name + ">"; if (name == end) return true; return false; } string nameTag(string demo) { int from = demo.find_first_of('<'); int off = fmin(demo.find_first_of(' '), demo.find_first_of('>')) - 1; return demo.substr(from + 1, off); } struct range { int from; int to; }; range rangeOfTag(string tags, string nameTag, int index = 0) { range result; result.from = 0; result.to = 0; string endTag = "</" + nameTag + ">"; nameTag = "<" + nameTag; unsigned long int j = 0, k = 0; for (unsigned long int i = index; i < tags.length(); i++) { if (tags[i] == nameTag[j]) { ++j; if (j == nameTag.length()) { result.from = i - j + 1; } } else j = 0; if (tags[i] == endTag[k]) { ++k; if (k == endTag.length()) { result.to = i - k + 1; } } else k = 0; } return result; } int indexEnd(string tags, string name) { int j = 0; for (int i = 0; i < tags.length(); i++) { if (tags.at(i) == name.at(j)) { ++j; if (j == name.length()) { return i - j; } } } return 0; } string solve(string tags, string querie, int index) { if (index < 0) return "Not Found!"; string temp = ""; string att; range correct; correct.from = index; correct.to = index; while (tags[correct.from] != ' ') --correct.from; while (tags[correct.to] != ' ') ++correct.to; vector<string> split; string name = tags.substr(correct.from + 1, correct.to - correct.from - 1); string templateS = ""; for (int i = 0; i < tags.length(); i++) { if (tags.at(i) == '<') { string temp = tags.substr(i + 1, fmin(tags.find('>', i + 1), tags.find(' ', i + 1)) - i - 1); range ran = rangeOfTag(tags, temp); if (ran.from < index && ran.to > index) { templateS = templateS + temp + '.'; } } } templateS[templateS.length() - 1] = '~'; templateS = templateS + name; string result = tags.substr(tags.find('"', index) + 1, tags.find('"', tags.find('"', index) + 1) - tags.find('"', index) - 1); if (querie == templateS) return result; return "Not Found!"; } int main() { int n, q; cin >> n >> q; cin.ignore(1, 'n'); map<string, string> tags; string title, temp = ""; bool check = true; for (int i = 0; i < n; i++) { string temp1; getline(cin, temp1); if (check) { title = nameTag(temp1); check = false; } temp = temp + temp1; if (checkEnd(title, temp1)) { tags[title] = temp; temp = ""; check = true; } } for (int i = 0; i < q; i++) { string querie; cin >> querie; int j = 0; string title = ""; while (!ispunct(querie.at(j)) && j < querie.length()) { title = title + querie.at(j); j++; } if (tags.find(title) != tags.end()) { int check = querie.find('~'); if (check) { string nameAttri = querie.substr(querie.find('~') + 1, querie.length() - querie.find('~')); int index = tags[title].find(nameAttri); string demo = solve(tags[title], querie, index); while (index >= 0) { if (demo != "Not Found!") break; index = tags[title].find(nameAttri, index + nameAttri.length() + 1); demo = solve(tags[title], querie, index); } cout << demo << endl; } else cout << "Not Found!"; } else { cout << "Not Found!" << endl; } } return 0; }
Second solution
#include <cmath> #include <cstdio> #include <vector> #include <iostream> #include <algorithm> #include <map> using namespace std; vector<string> tag_stack; map<string, string> attrs; void insert_attr(string & name, string & val) { string full; for(string & str : tag_stack) full += str + "."; full.pop_back(); full += "~" + name; attrs[full] = val; } int main() { int n, q; cin >> n >> q; for(int i = 0; i < n; ++i) { char c; cin >> c; if(cin.peek() == '/') { // close string cn; cin >> cn; tag_stack.pop_back(); } else { //open' string name; cin >> name; if(name.back() == '>') { //no attrs name.pop_back(); tag_stack.push_back(name); } else { tag_stack.push_back(name); for(;;) { string attr_name, attr_val, eq; cin >> attr_name >> eq >> attr_val; if(attr_val.back() == '>') { //last attr attr_val.pop_back(); attr_val.pop_back(); attr_val = attr_val.substr(1); insert_attr(attr_name, attr_val); break; } else { attr_val.pop_back(); attr_val = attr_val.substr(1); insert_attr(attr_name, attr_val); } } } } } for(int i = 0; i < q; ++i) { string quer; cin >> quer; if(attrs.find(quer) != attrs.end()) cout << attrs[quer] << endl; else cout << "Not Found!" << endl; } return 0; }
How much time did it take you to complete this?
2 years
damn!!(⓿_⓿)