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;
}
Subscribe to:
Post Comments (Atom)
Task in UnrealEngine
https://www.youtube.com/watch?v=1lBadANnJaw
-
Unity released very good FPS example for people and I decided to analysis how they make this. Personally I wanted to show you how I analys...
-
When we use DrawDebugSphere function for debugging, it is working well but when you are trying to use it in anim node's function it will...
-
If you press a key 'L' in the jupyter notebook then you can see the line number in the editor.
No comments:
Post a Comment