We use cookies to ensure you have the best browsing experience on our website. Please read our cookie policy for more information about how we use cookies.
I ended up changing everything I had written below because I couldn't sleep at night with how ugly the code was. I seemed to have ended up with an approach similar to yours:
1) Create a tag struct, that contains:
i) name
ii) a map for tags
iii) a map for attributes/values
iv) pointer to parent tag
2) Create a master map, that contains all first level tags
3) Create a current tag so that we can nest into and close them out.
#include<cstdio>#include<iostream>#include<sstream>#include<map>usingnamespacestd;structtagobj{stringname;map<string,tagobj*>tmap;map<string,string>map_att;tagobj*prev=NULL;};voiddelete_tags(tagobj*tag){for(map<string,tagobj*>::iteratori=tag->tmap.begin();i!=tag->tmap.end();i++){delete_tags(i->second);}delete(tag);}intmain(){//Setup a vector holding all first level tagsmap<string,tagobj*>main;//Current depth so as to nesttagobj*masterTag=NULL;inttlines,qlines;stringints;getline(cin,ints);stringstreamss(ints);ss>>tlines;ss>>qlines;stringline;size_tdel_tag;//Save the information for(inti=0;i<tlines;i++){//Get Tag from linegetline(cin,line);del_tag=line.find_first_of(" >");stringtag=line.substr(1,del_tag-1);//opening tagsif(tag[0]!='/'){//Create Structtagobj*currTag=newtagobj();currTag->prev=masterTag;currTag->name=tag;//check if we add to master vector or previous:if(!masterTag){main[currTag->name]=currTag;}else{masterTag->tmap[currTag->name]=currTag;}masterTag=currTag;//Add all attributessize_tfound=line.find("=",del_tag);while(found!=string::npos){//Get the attributestringname=line.substr(del_tag+1,found-del_tag-2);//move past the =del_tag=found+2;found=line.find("\"",del_tag+1);//Copy the valuestringvalue=line.substr(del_tag+1,found-del_tag-1);//add to mapcurrTag->map_att[name]=value;//keep goingdel_tag=line.find(" ",found);found=line.find("=",found);}}else{//If its a closing Tag return main tag to its previousmasterTag=masterTag->prev;}}for(inti=0;i<qlines;i++){tagobj*masterq=NULL;getline(cin,line);size_tstart=0;stringval;boolfnd;while(true){size_tfound=line.find_first_of(".~",start);stringbuff=line.substr(start,found-start);fnd=false;//looking for attributeif(start>0&&line[start-1]=='~'){//Attributes have a sentinal//Check for bad inputif(masterq){val=masterq->map_att[buff];if(!val.empty()){fnd=true;}break;}}else{//Looking for a tag, if found, continue lookingmap<string,tagobj*>*bufobj=NULL;//Make sure to look in right placeif(masterq){bufobj=&(masterq->tmap);}else{bufobj=&main;}tagobj*frommap=(*bufobj)[buff];if(frommap){masterq=frommap;}else{break;}}start=found+1;}//Printing Time:if(fnd){cout<<val<<endl;}else{cout<<"Not Found!"<<endl;}}for(map<string,tagobj*>::iteratori=main.begin();i!=main.end();i++){delete_tags(i->second);}}
Cookie support is required to access HackerRank
Seems like cookies are disabled on this browser, please enable them to open this website
Attribute Parser
You are viewing a single comment's thread. Return to all comments →
I ended up changing everything I had written below because I couldn't sleep at night with how ugly the code was. I seemed to have ended up with an approach similar to yours:
1) Create a tag struct, that contains:
2) Create a master map, that contains all first level tags
3) Create a current tag so that we can nest into and close them out.