문제 링크
난이도 : Lv. 2
문제 내용
문제 설명
다음 규칙을 지키는 문자열을 올바른 괄호 문자열이라고 정의합니다. (), [], {} 는 모두 올바른 괄호 문자열입니다. 만약 A가 올바른 괄호 문자열이라면, (A), [A], {A} 도 올바른 괄호 문자열입니다. 예를 들어, [] 가 올바른 괄호 문자열이므로, ([]) 도 올바른 괄호 문자열입니다. 만약 A, B가 올바른 괄호 문자열이라면, AB 도 올바른 괄호 문자열입니다. 예를 들어, {} 와 ([]) 가 올바른 괄호 문자열이므로, {}([]) 도 올바른 괄호 문자열입니다. 대괄호, 중괄호, 그리고 소괄호로 이루어진 문자열 s가 매개변수로 주어집니다. 이 s를 왼쪽으로 x (0 ≤ x < (s의 길이)) 칸만큼 회전시켰을 때 s가 올바른 괄호 문자열이 되게 하는 x의 개수를 return 하도록 solution 함수를 완성해주세요. 제한사항 s의 길이는 1 이상 1,000 이하입니다. 입출력 예
입출력 예 설명 입출력 예 #1 다음 표는 ”[](){}” 를 회전시킨 모습을 나타낸 것입니다. x s를 왼쪽으로 x칸만큼 회전 올바른 괄호 문자열?
올바른 괄호 문자열이 되는 x가 3개이므로, 3을 return 해야 합니다. 입출력 예 #2
올바른 괄호 문자열이 되는 x가 2개이므로, 2를 return 해야 합니다. 입출력 예 #3 s를 어떻게 회전하더라도 올바른 괄호 문자열을 만들 수 없으므로, 0을 return 해야 합니다. 입출력 예 #4 s를 어떻게 회전하더라도 올바른 괄호 문자열을 만들 수 없으므로, 0을 return 해야 합니다.
문제 분석
올바른 괄호가 나오면 삭제하기 위해 스택을 사용함.
특정 인덱스부터 시작해서 순환하는 형태로 스택에 데이터를 넣기 위해 함수를 만듬
좀 더 보기 편하게 나는 괄호에 숫자를 부여해서, top 데이터랑 다음 데이터가 더해서 0이 되면 사라지게 했음.
(는 1, )는 -1 이런식으로
작성한 코드
// 250407
#include <string>
#include <vector>
#include <stack>
#include <iostream>
using namespace std;
vector<int> bToi(string s) {
vector<int> arr(s.size());
for(int i = 0; i < s.size(); i++) {
if(s[i] == '(') arr[i] = 1;
else if(s[i] == ')') arr[i] = -1;
else if(s[i] == '[') arr[i] = 2;
else if(s[i] == ']') arr[i] = -2;
else if(s[i] == '{') arr[i] = 3;
else if(s[i] == '}') arr[i] = -3;
}
return arr;
}
bool IsGoodStr(vector<int> &arr, int start) {
stack<int> st;
int i = start;
// cout << "Start index : " << i << endl;
int count = 0;
while(count < arr.size()) {
if(arr[i] > 0) {
st.push(arr[i]);
}
else {
if(st.empty()) return false;
else {
// cout << "Top : " << st.top() << " Next : " << arr[i] << endl;
if(st.top() + arr[i] == 0){
st.pop();
}
else {
return false;
}
}
}
i++;
if(i > arr.size() - 1) i = 0;
count++;
}
if(st.empty()) {
/*
cout << "Start Index " << start << " is Good Str" << endl;
*/
return true;
}
else {
// cout << "Start Index " << start << " is Not Good Str" << endl;
return false;}
}
int solution(string s) {
vector<int> arr = bToi(s);
/*
cout << "To Int : " ;
for(int i = 0; i < arr.size(); i++) {
cout << arr[i] << " ";
}
cout << endl;
*/
int answer = 0;
for(int i = 0; i < arr.size(); i++) {
stack<int> st;
if(IsGoodStr(arr, i)) answer++;
}
return answer;
}
우수 코드 분석
// 프로그래머스 책 참고
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
unordered_map<char char> bracketPair = {{')', '('}, {']', '['}, {'}', '{'}};
bool isValid(string &s, int start) {
stack<char> stk;
unsigned int sz = s.size();
for(int i = 0; i < sz; i++) {
char ch = s[(start + i) % sz];
if (bracketPair.count(ch)) {
if (stk.empty() || stk.top() != bracketPair[ch])
return false;
stk.pop();
} else stk.push(ch);
}
return stk.empty();
}
int solution (string s){
int answer = 0;
int n = s.size();
for(int i = 0; i < n; i++){
answer += isValid(s, i);
}
return answer;
}
unordered_map 에서 요소를 찾을 때 count, find를 사용하는데,
count는 해당 키를 가진 요소의 갯수를 출력하고
find는 이터레이터를 반환하기 때문에 이후 처리가 조금 다름.
여기서는 있냐 없냐가 중요했기 때문에 count를 사용했음.
키값을 닫힌 괄호로 했음. 그래서 저 위에 count(ch)는 닫힌 괄호냐 아니냐 라는 의미를 가짐
나는 괄호를 숫자화 한거고, 여기 예제는 괄호를 맵으로 구성한 것임.