12. Attribute Parser
1. 내용 정리
이번 챌린지는 custom-designed markup language인 HRML을 사용한다.
HRML에서는 각 요소들은 시작 태그와 종료 태그로 둘러싸여 있고 각 태그를 포함하도록 되어있다.
오직 시작 태그만의 attribute를 가질 수 있다.
틸다 '~'라고 하는 래퍼렌싱 태그를 사용함으로써 attribute를 부를 수 있다.
태그는 중첩될 수도 있다.
시작 태그는 아래의 형식을 따른다:
<tag-name attribute1-name = "value1" attribute2-name = "value2" ... >
종료 태그는 아래의 형식을 따른다:
</tag-name>
attribute는 아래처럼 사용한다:
tag1~value
tag1.tag2~name
2. 과제
과제 설명
HRML 형식으로 작성된 주어진 소스코드는 N 줄을 포함하고 Q 쿼리들을 답한다.
각 쿼리는 특정된 attribute 값을 반환한다.
만약 attribute가 존재하지 않을 경우, "Not Found!"를 출력하라.
예시
HRML listing
<tag1 value = "value">
<tag2 name = "name">
<tag3 another="another" final="final">
</tag3>
</tag2>
</tag1>
Queries
tag1~value
tag1.tag2.tag3~name
tag1.tag2~value
여기서, tag2는 tag1을 nested하고 있고, 그리고 tag2의 attribute는 tag1.tag2~<attribute>로 접근할 수 있다.
쿼리의 결과는 아래와 같다:
Query Value
tag1~value "value"
tag1.tag2.tag3~name "Not Found!"
tag1.tag2.tag3~final "final"
입력 형식
첫 번째 줄은 두 개의 공백으로 분리된 정수, N과 Q로 이루어져 있다.
N은 HRML 소스 프로그램의 줄 수를 나타낸다.
Q는 쿼리의 줄 수를 나타낸다.
N 개의 줄은 0개 또는 그 이상 attribute의 시작 태그 또는 종료 태그로 구성되어 있다.
태그 이름, attribute 이름, '=' 그리고 값 이후에 공백이 있다.
마지막 값 뒤에는 공백이 없다.
만약 attribute가 없다면 태그 이름 뒤에는 공백이 없다.
Q 쿼리는 다음을 따른다. 각 쿼리는 소스 프로그램 내에서의 attribute를 참조하는 문자열을 포함한다.
좀 더 형식적으로, 각 쿼리는 tag_i1, tag_i2, tag_i3,...,tag_im~attr-name 형식을 갖고(m은 1보다 크거나 같다.) tag_i1, tag_i2, ..., tag_im은 입력에서의 활성화된 태그이다.
제약 사항
N은 1보다 크거나 같고 20보다 작거나 같다.
Q는 1보다 크거나 같고 20보다 작거나 같다.
소스 프로그램의 각 줄은 거의 200자이다.
Q 쿼리에 있는 attribute를 참조하는 모든 것은 거의 200자이다.
모든 태그 이름들은 다 unique하고 HRML 소스 프로그램은 논리적으로 옳다.(i.e. valid nesting)
태그는 attribute가 없다.
출력 형식
각 쿼리의 attribute 값을 출력하라.
만약 attribute가 존재하지 않다면 "Not Found!"를 큰따옴표를 제외하고 출력하라.
입력 예시
4 3
<tag1 value = "HelloWorld">
<tag2 name = "Name1">
</tag2>
</tag1>
tag1.tag2~name
tag1~name
tag1~value
출력 예시
Name1
Not Found!
HelloWorld
문제
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
return 0;
}
정답
#include <iostream>
#include <vector>
#include <map>
#include <sstream>
#include <algorithm>
using namespace std;
int main() {
int n, q;
cin >> n >> q;
cin.ignore();
vector<string> hrml;
vector<string> quer;
for (int i = 0; i < n; i++) {
string temp;
getline(cin, temp);
hrml.push_back(temp);
}
for (int i = 0; i < q; i++) {
string temp;
getline(cin, temp);
quer.push_back(temp);
}
map<string, string> m;
vector<string> tag;
for (int i = 0; i < n; i++) {
string temp = hrml[i];
temp.erase(remove(temp.begin(), temp.end(), '\"'), temp.end());
temp.erase(remove(temp.begin(), temp.end(), '>'), temp.end());
if (temp.substr(0, 2) == "</") {
tag.pop_back();
} else {
stringstream ss;
ss.str("");
ss << temp;
string t1, p1, v1;
char ch;
ss >> ch >> t1 >> p1 >> ch >> v1;
string temp1 = "";
if (tag.size() > 0) {
temp1 = *tag.rbegin();
temp1 = temp1 + "." + t1;
} else {
temp1 = t1;
}
tag.push_back(temp1);
m[*tag.rbegin() + "~" + p1] = v1;
while (ss) {
ss >> p1 >> ch >> v1;
m[*tag.rbegin() + "~" + p1] = v1;
}
}
}
for (int i = 0; i < q; i++) {
if (m.find(quer[i]) == m.end()) {
cout << "Not Found!\n";
} else {
cout << m[quer[i]] << endl;
}
}
return 0;
}
이거와 관련하여 더 공부가 필요할 것으로 예상...
©️Hackerrank. All Rights Reserved.
'프로그래밍 언어 > C, C++' 카테고리의 다른 글
[Hackerrank] 40. Overload Operators (0) | 2024.03.05 |
---|---|
[Hackerrank] 39. Operator Overloading (0) | 2024.03.02 |
[Hackerrank] 38. Preprocessor Solution (0) | 2024.03.01 |
[Hackerrank] 37. C++ Class Templates (0) | 2024.03.01 |
[Hackerrank] 36. Magic Spells (3) | 2024.02.29 |