Skip to content

Instantly share code, notes, and snippets.

@jatinsharrma
Created March 17, 2021 14:28
Show Gist options
  • Save jatinsharrma/41580a67ba41b0262bc555c8d9a51790 to your computer and use it in GitHub Desktop.
Save jatinsharrma/41580a67ba41b0262bc555c8d9a51790 to your computer and use it in GitHub Desktop.
c++ | Attribute Parser | Hackerrank
// problem link : https://www.hackerrank.com/challenges/attribute-parser/problem
#include <iostream>
#include <vector>
const int start = 1;
const int end = 0;
//------------User defined Data types ----------------
struct Attribute{
std::string name;
std::string value;
int type; // 1 means not last, 0 means last
Attribute(std::string n, int t = start):
name(n), type(t) {}
};
struct Tag{
std::string name;
std::vector<Attribute> attrib;
std::vector<Tag> child;
int type; // 1 means end tag not seen 0 means end tag seen
Tag(std::string n, int t = start):
name(n), type(t){}
};
struct Query{
std::vector<std::string> tags;
std::string attribute;
Query(std::string);
};
//--------------Query Builder-----------------
Query::Query(std::string s)
{
std::string temp;
int i;
for( i=0; i<s.size() ; i++){
if (s[i] == '.' || s[i] == '~') {
tags.push_back(temp);
temp = "";
if (s[i] == '~') break;
continue;
}
temp.push_back(s[i]);
}
for (int j=i+1 ; j<s.size() ; j++){
attribute.push_back(s[j]);
}
}
// ---------------User Data Types enede----------------
//-----------Function declarations -------------------
Tag read_tag(); // read tag from user
Attribute read_attribute(); // read attribute of tags from user
Tag last_member(std::vector<Tag>&); // pop last elemet of the vector and return the same
void print_tag(std::vector<Tag>&, std::string); // print tags
void query_result(Query& ,std::vector<Tag>); // deal with query's tag part
void print_query(Query); // print query
void print_result(std::vector<Attribute>, Attribute); // deal with query's attribute part and print query result
// ----------------Execution starts here---------------
int main()
{
int l;
std::cin >> l;
int q;
std::cin >> q;
std::vector<Tag> stack; // store tag untile all childs are seen
std::vector<Tag> all_tags; // store all complete tags
for (int i=0 ; i<l ; i++){
Tag tag = read_tag();
if (tag.type)
stack.push_back(tag);
else{
Tag child = last_member(stack);
if(stack.size()){
Tag parent = last_member(stack);
parent.child.push_back(child);
stack.push_back(parent);
}
else{
all_tags.push_back(child);
}
}
}
//print_tag(all_tags, "Parent");
for(int i=0; i<q ; i++){
std::string s;
std::cin >> s;
Query n(s);
query_result(n,all_tags);
}
}
Tag read_tag()
{
std::string name;
std::cin >> name;
//seen end tag
if (name[0] == '<' && name[1] == '/'){
name = name.substr(2,(name.size()-2));
return Tag(name,end);
}
//not seen end tag
else if (name[0] == '<'){
// no attribute tag
if (name.back() == '>'){
name = name.substr(1,(name.size()-2));
return Tag(name);
}
// tags with attributes
else{
name = name.substr(1,(name.size()-1));
Tag temp(name);
//get all attributes
while(true){
Attribute attriib = read_attribute();
temp.attrib.push_back(attriib);
if (!attriib.type) break;
}
return temp;
}
}
return Tag("Wrong");
}
Attribute read_attribute(){
std::string name;
std::string value;
std::getline( std::cin,name,'=');
std::cin >> value;
// removing whitespace from front
name.erase(0,1);
//removing whitespace from back
if (name.back() == ' ') name = name.substr(0, (name.size()- 1));
Attribute attrib(name);
//last attribute seen
if (value.back() == '>'){
attrib.type = end;
attrib.value = value.substr(1,(value.size()-3)); // 3 because we have ' "> ' in last
}
// last attribute not seen
else attrib.value = value.substr(1,(value.size()-2)); // 2 because we have ' " ' in last
return attrib;
}
Tag last_member(std::vector<Tag>& stack)
{
Tag last = stack.back();
stack.pop_back();
return last;
}
void print_tag(std::vector<Tag>& tags, std::string s)
{
for (int p=0 ; p<tags.size(); p++){
std::cout << s << " Tag : " << tags[p].name ;
std::cout << " | Attributes :: ";
for (int a=0 ; a< tags[p].attrib.size(); a++)
std::cout << tags[p].attrib[a].name << ":\"" << tags[p].attrib[a].value << "\" ";
std::cout << std::endl;
std::string s = "\tChild of " + tags[p].name;
print_tag(tags[p].child , s);
}
}
void query_result(Query& q, std::vector<Tag> all_tags)
{
if(q.tags.size()){
for(int i=0; i<all_tags.size() ; i++){
if (all_tags[i].name == q.tags[0]){
//erasing top tag from query's tags because we have seen it.
q.tags.erase(q.tags.begin());
//if query has more tags return child of current tag
if (q.tags.size()) query_result(q, all_tags[i].child);
// if query has no more tags return currnent tag's attribute vector
else print_result(all_tags[i].attrib, q.attribute);
return;
}
}
}
std::cout << "Not Found!" <<std::endl;
}
void print_result(std::vector<Attribute> a, Attribute sa)
{
for (int i=0 ; i<a.size(); i++){
if(a[i].name == sa.name) {
std::cout << a[i].value <<std::endl;
return;
}
}
std::cout << "Not Found!" <<std::endl;
}
void print_query(Query q)
{
std::cout << "Tags : ";
for(int i=0 ; i<q.tags.size() ; i++)
std::cout << q.tags[i];
std::cout << std::endl;
std::cout << "Attribute : "<< q.attribute <<std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment