Attribute Parser

Sort by

recency

|

481 Discussions

|

  • + 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;
    }
    
  • + 0 comments

    Probably no the best solution, but it works:

    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    
    void ltrim(string &s) {
        s.erase(s.begin(), find_if(s.begin(), s.end(), [](unsigned char ch) {
            return !isspace(ch);
        }));
    }
    
    void delete_quotes(string &s) {
        if (s.size() >= 2 && s.front() == '"' && s.back() == '"') {
            s.erase(s.begin());
            s.pop_back();
        }
    }
    
    int main() {
           
        int n, q;
        
        cin >> n >> q;
        
        vector<string> tag_stack;
        map<string, string> attrs;
        
        cin.ignore();
        
        for (int i = 0; i < n; i++) {
            string line;
            getline(cin, line);
            
            if (line[1] != '/') {
                string tag;
                size_t position = 1; // Start from position 1 to ignore the tag opening '<'
    
                // Capture the tag name:
                while (position < line.size()) {
                    // If a space or '>' is found, the tag name is complete
                    if (line[position] == ' ' || line[position] == '>') break;
                    tag += line[position++]; // The increment is performed after the character is added
                }
    
                tag_stack.push_back(tag); // Add the tag to the stack
    
                string path = tag_stack[0];
                
                // Create the tag path:
                for (int j = 1; j < tag_stack.size(); j++) path += ("." + tag_stack[j]);
                
                // Create a substring considering only the attributes and their values
                string attributes = line.substr(position, line.length() - position - 1); // Exclude the closing '>'
                ltrim(attributes);
                
                // Assign the attributes to the path
                attrs[path] = attributes;
            } else {
                tag_stack.pop_back();
            }
        }
        
        for (int i = 0; i < q; ++i) {
            string query;
            getline(cin, query);
    
            size_t tilde = query.find('~');
            string path = query.substr(0, tilde);
            string attr = query.substr(tilde + 1);
    
            if (attrs.count(path)) {
                string tag_attrs = attrs[path];
                size_t position = tag_attrs.find(attr);
    
                if (tag_attrs.find(attr) != string::npos && (position == 0 || isspace(tag_attrs[position - 1]))) {
                    string value;
                    position += attr.length() + 3; // Skip ' = '
    
                    // Capture the value of the attribute:
                    while (position < tag_attrs.length() && tag_attrs[position] != ' ') value += tag_attrs[position++];
    
                    delete_quotes(value);
    
                    cout << value << endl;
                } else {
                    cout << "Not Found!" << endl;
                }
            } else {
                cout << "Not Found!" << endl;
            }
        }
    }
    
  • + 1 comment
    int main() {
        
        int n, q;
        cin>>n>>q;
        cin.ignore();
        
        map<string, map<string, string>> hrml;
        string line, path = "";
        
        while (n-->0) {
            getline(cin, line);
            stringstream ss(line);
            
            string token;
            ss >> token;
            
            if(token[1]=='/'){
                size_t pos = path.rfind('.');
                if(pos!=string::npos){
                    path = path.substr(0, pos);
                }else{
                    path = "";
                }
            }else{
                string tag = token.substr(1);
                if(!tag.empty() && tag.back() == '>') tag.pop_back();
                
                if(!path.empty()){
                    path += "." + tag;
                }else{
                    path = tag;
                }
                
                string attr, eq, value;
                while (ss >> attr >> eq >> value) {    
                    
                    if(value.front()=='"'){
                        if(!value.empty() && value.back() == '>') value.pop_back();
                        value = value.substr(1, value.size() - 2);
                    }
                     
                    hrml[path][attr]=value;
                }
            }
        }
        
        while (q-->0) {
            getline(cin, line);
            size_t tilPos = line.find('~');
            string tagPath = line.substr(0,tilPos);
            string attr = line.substr(tilPos + 1);
            
            if(hrml.count(tagPath) && hrml[tagPath].count(attr)){
                cout<<hrml[tagPath][attr]<<endl;
            }else{
                cout<<"Not Found!"<<endl;
            }
        }
           
        return 0;
    }
    
  • + 0 comments

    include

    include

    include

    include

    include

    using namespace std;

    int main() { int n, q; cin >> n >> q; cin.ignore();

    map<string, string> attributes;
    string line, tag_path = "";
    
    for (int i = 0; i < n; ++i) {
        getline(cin, line);
        // Remove '<' and '>'
        line.erase(remove(line.begin(), line.end(), '>'), line.end());
        line.erase(remove(line.begin(), line.end(), '<'), line.end());
    
        stringstream ss(line);
        string word;
        ss >> word;
    
        if (word[0] == '/') {
            // Closing tag
            size_t pos = tag_path.rfind('.');
            if (pos != string::npos) {
                tag_path = tag_path.substr(0, pos);
            } else {
                tag_path = "";
            }
        } else {
            // Opening tag
            string tag_name = word;
            if (!tag_path.empty()) {
                tag_path += "." + tag_name;
            } else {
                tag_path = tag_name;
            }
    
            // Parse attributes
            string attr_name, eq, attr_value;
            while (ss >> attr_name >> eq >> attr_value) {
                // Remove quotes from attr_value
                attr_value = attr_value.substr(1, attr_value.length() - 2);
                string key = tag_path + "~" + attr_name;
                attributes[key] = attr_value;
            }
        }
    }
    
    for (int i = 0; i < q; ++i) {
        string query;
        getline(cin, query);
        if (attributes.find(query) != attributes.end()) {
            cout << attributes[query] << endl;
        } else {
            cout << "Not Found!" << endl;
        }
    }
    
    return 0;
    

    }

  • + 0 comments

    Here is Attribute Parser solution in c++ - https://programmingoneonone.com/hackerrank-attribute-parser-solution-in-cpp.html