Attribute Parser

  • + 0 comments

    This solutions makes use of Composite to fully show the hierachy of the tags.

    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <sstream>
    #include <map>
    using namespace std;
    
    
    struct TagNode {
        string name;
        map< std::string, std::string > attributes;
        vector< TagNode* > children;
    
        ~TagNode() {
            for ( auto child : children ) {
                delete child;
            }
        }
    };
    
    
    string queryAttribute( TagNode * root, const std::string& query ) {
        istringstream iss( query );
        string path;
        getline( iss, path, '~' );
        string attribute;
        getline( iss, attribute );
    
        TagNode* current = root;
        istringstream pathIss( path );
        string tag;
        
    
        while ( getline( pathIss, tag, '.' ) ) {
            bool found = false;
            for ( auto child : current->children ) {
                if ( child->name == tag ) {
                    current = child;
                    found = true;
                    break;
                }
            }
            if ( !found ) return "Not Found!";
        }
    
        auto it = current->attributes.find( attribute );
        if ( it != current->attributes.end() ) return it->second;
        else                                   return "Not Found!";
    }
    
    
    
    int main() {
        int N, Q;
        
        cin >> N >> Q;
        string line = "";
        cin.ignore();
        vector< TagNode * > currentNode;
        TagNode * root = new TagNode;
        currentNode.push_back( root );
        
        while( N-- > 0 ) {
            string str; 
            getline( cin, str );
            
            if( str[ 1 ] != '/' ) {
                int leer = str.find( ' ' );
                if( leer == string::npos ) {
                    leer = str.size() - 1;
                }
    
                TagNode* node = new TagNode;
                node->name = str.substr( 1, leer - 1 );
                
                str = str.substr( leer + 1 );
                while( str.empty() == false ) {
                    int nameEnd = str.find( ' ' );
                    string key =  str.substr( 0, nameEnd );
                    str = str.substr( nameEnd + 4 );
                    int valueEnd   = str.find( '"' );
                    string value   = str.substr( 0, valueEnd );
                    str = str.substr( valueEnd + 2 );
                    node->attributes[ key ] = value;
                }
                
    
                currentNode.back()->children.push_back( node );
                currentNode.push_back( node );
            }
            else {
                currentNode.pop_back();
            }
        }
    
        while( Q-- > 0 ) {
            string line;
            cin >> line;
            cout << queryAttribute( root, line ) << "\n";
        }
    
        return 0;
    }