본문 바로가기

프로그래밍 언어/C, C++

[Hackerrank] 12. Attribute Parser

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.