Thursday, October 24, 2019

I like hackerrank because I can see other people's solution which is exactly same problem.

I've just solved 'Attribute Parser' problem on hackerrank. After I solved this problem and I had a look at the discussion to see other people's solution. I can see many good implementation!! I should learn from them. :) I think comparing other people's source code is really good way to think differently. My implementation is down below.


--------
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <map>
#include <cstring>

using namespace std;

/*struct NameEquals
{
    bool operator() (const Tag& rhs) const
    {
        return name == rhs.tagName;
    }
    NameEquals(const string str) : name(str) {}
private:
    const string name;
};*/

class Tag
{
public:
    Tag(int _level, string data)
        : level(_level)
    {
        int index = data.find(' ');

        if (index != string::npos)
        {
            // get the tag's name not attribute name.           
            tagName = data.substr(1, index - 1);
            indexAftertagName = index;
            //cout << tagName << endl;
        }
        else
        {
            noattribute = true;
            tagName = data.substr(1, data.size() - 2);
        }
    }

    void readAttributes(string data)
    {
        // attributeName1 = "blabla" attributeName2 = "blablabla" ... >

        if (noattribute) return;

        int i = indexAftertagName + 1;
        const char* p = data.c_str() + i;

        while (true)
        {
            char ch = *p;
            if (isalpha(ch)) // attributeName
            {
                const char* attrP = p;
                while (*p != ' ') p++; // find out the empty
                const int len = p - attrP;               
                string attributeName = std::string(attrP, len);

                while (*p != '"') p++;

                const char* value = ++p;

                while (*p != '"') p++;

                const int valueLen = p - value;
                string attributeValue = std::string(value, valueLen);

                attributes.insert(make_pair(attributeName, attributeValue));
            }
            else
            {
                p++;
                if (*p == 0) break;
            }
        }
    }

    void addChildTag(Tag* newTag)
    {
        childTags.push_back(newTag);
    }

    void command(char ch, const char* data)
    {
        if (ch == '.')
        {
            // find child tag
            const char* childName = data + 1;
            const char* p = childName;
            while (*p != '.' && *p != '~') p++;
            string childTagName = std::string(childName, p - childName);
           
            bool foundTag = false;
            for (auto element : childTags)
            {
                if (element->tagName == childTagName)
                {
                    foundTag = true;
                    element->command(*p, p);
                    break;
                }
            }                     

            if ( !foundTag )
            {
                cout << "Not Found!" << endl;               
            }
        }
        else if (ch == '~')
        {           
            // find an attribute
            const char* pAttributeName = data + 1;
            const char* p = pAttributeName;
            while (*p) p++;
            string attributeName = std::string(pAttributeName, p - pAttributeName);
           
            auto elementIter = attributes.find(attributeName);

            if (elementIter != attributes.end())
            {
                cout << elementIter->second << endl;
            }
            else
            {
                cout << "Not Found!" << endl;
            }
        }
    }
   
    int level;
    int indexAftertagName;
    bool noattribute;
    string tagName;
    map<string, string> attributes;
    vector<Tag*> childTags;
};



/*
<tag1 value = "HelloWorld">
<tag2 name = "Name1">
</tag2>
</tag1>
*/

int main() {
    int n; // count of tags
    int q; // query
    cin >> n >> q;

    // skip escape char
    char c;
    c = cin.get();

    int level = 0;

    vector<Tag*> tags;
    stack<Tag*> stackTags;

    for (int i = 0; i < n; ++i)
    {
        string data;
        std::getline(cin, data);

        //cout << "read : " << data << endl;

        // checks whether it start with </ or <%alphabet
        if (data.at(0) == '<' && data.at(1) == '/')
        {
            // end of tag
            level--;
            stackTags.pop();
        }
        else
        {
            Tag* newTag = new Tag(level, data);

            newTag->readAttributes(data);
         
            if (stackTags.size() == 0)
            {
                tags.push_back(newTag);
                stackTags.push(newTag);
            }
            else
            {
                // add this tag as a child
                stackTags.top()->addChildTag(newTag);
                stackTags.push(newTag);
            }


            level++;
        }
    }

    for (int i = 0; i < q; ++i)
    {
        string data;
        std::getline(cin, data);
       
        const char* p = data.c_str();
        const char* tagNameP = data.c_str();;
        while (*p != '.' && *p != '~') p++;

        const string tagName = std::string(tagNameP, p - tagNameP);

        //auto iter = std::find_if(tags.begin(), tags.end(), NameEquals(tagName));
        bool tagFound = false;
        for (auto element : tags)
        {
            if (element->tagName == tagName)
            {
                tagFound = true;
                element->command(*p, p);
                break;
            }
        }

        if ( !tagFound)
        {
            cout << "Not Found!" << endl;           
        }
    }


   
    return 0;
}






No comments:

Post a Comment

Task in UnrealEngine

 https://www.youtube.com/watch?v=1lBadANnJaw