https://www.acmicpc.net/problem/5076
괄호검사와 비슷한 맥락으로 스택만 사용하면 쉽게 풀 수 있는 문제이다.
하지만 문자열 파싱이 필요하므로 훨씬 복잡해진 문제.
파이썬에서 문자열 처리하다가 C++ 문자열 처리를 하면.. 매우 하기 싫어진다 ㅜㅜ
문제가 영어라서 약간 당황했는데 마크업 언어의 구조만 알고 있다면 문제를 읽는데 무리가 없다.
친절하게도 정상적인 태그가 아니라면 input에 꺾쇠 부호가 나오지 않는다고 알려주고 있다.
#include <iostream>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
using namespace std;
void parse(string s) {
stack<string> st;
int pos = 0;
while (s.find("<", pos) != string::npos) {
// 태그 따기
int start_pos = (int)s.find("<", pos);
int end_pos = (int)s.find(">", pos);
string tag = s.substr(start_pos + 1, end_pos - start_pos - 1);
//공백으로 split해서 vector 집어넣음
vector<string> tag_v;
char str_buff[255];
strcpy(str_buff, tag.c_str());
char* tok = strtok(str_buff, " ");
while (tok != nullptr) {
tag_v.push_back(string(tok));
tok = strtok(nullptr, " ");
}
if (tag_v.back() == "/") {} //마지막 원소가 /면 아무것도 안함
else if (tag_v[0][0] == '/') {
if (!st.empty() && st.top() == tag_v[0].substr(1, tag_v[0].length())) {
st.pop();
}
else {
cout << "illegal\n";
return;
}
}
else {
st.push(tag_v[0]);
}
pos = end_pos + 1;
}
if (!st.empty()) cout << "illegal\n";
else cout << "legal\n";
}
int main() {
string text;
while (getline(cin, text)) {
if (text == "#") break;
parse(text);
}
}
괄호검사 프로그램을 짜봤다면 이 문제 알고리즘 짜는데는 무리가 없을 듯!
그러나 이 문제를 풀면서 또다시 다양한 문자열 처리 방법에 대해 알게 되었으므로 나중에 이 부분에 대해 정리해봐야겠다.
'Algorithm > 백준' 카테고리의 다른 글
[백준] 1182번: 부분수열의 합 (0) | 2020.03.28 |
---|---|
[백준] 1874번: 스택 수열 (0) | 2020.03.23 |
[백준] 2304번: 창고 다각형 (0) | 2020.03.22 |
[백준] 1725번: 히스토그램 (0) | 2020.03.20 |
[백준] 1935번: 후위 표기식2 (0) | 2020.03.19 |