해결된 질문
작성
·
86
1
우선 제 로직은
// stk이 비어있는 경우
// ch가 열린 괄호인 경우
// push(ch);
// ch가 닫힌 괄호인 경우
// push(ch); break;
// stk이 비어있지 않은 경우
// ch가 열린 괄호인 경우
// top()이 닫힌 괄호인 경우 && 형태가 다름
// top()이 닫힌 괄호인 경우 && 형태가 같음
// top()이 열린 괄호 && 형태가 다름
// top()이 열린 괄호 && 형태가 같음
// ==> 위의 4경우 모두 push(ch);
// ch가 닫힌 괄호인 경우
// top()이 닫힌 괄호인 경우 && 형태가 다름
// top()이 닫힌 괄호인 경우 && 형태가 같음
// ==> 위의 2경우 모두 push(ch);
// top()이 열린 괄호인 경우
// 형태가 다른 경우
// break;
// 형태가 같은 경우
// pop();
// stk이 비어있는 경우
// yes
// stk이 비어있지 않는 경우
// no
입니다.
#include <bits/stdc++.h>
using namespace std;
int main(){
string input;
getline(cin,input);
string ret;
while(input!="."){
stack<char> stk;
for(int i=0;i<input.size();i++){
char ch=input.c_str()[i];
if(ch!='('&&ch!=')'&&ch!='['&&ch!=']') continue;
// stk이 비어있는 경우
if(stk.empty()){
// ch가 열린 괄호인 경우
if(ch=='('||ch=='['){
// push(ch);
stk.push(ch);
}
// ch가 닫힌 괄호인 경우
else{
// push(ch); break;
stk.push(ch);
break;
}
}
// stk이 비어있지 않은 경우
else{
// ch가 열린 괄호인 경우
if(ch=='('||ch=='['){
// top()이 닫힌 괄호인 경우 && 형태가 다름
// top()이 닫힌 괄호인 경우 && 형태가 같음
// top()이 열린 괄호 && 형태가 다름
// top()이 열린 괄호 && 형태가 같음
// ==> 위의 4경우 모두 push(ch);
stk.push(ch);
}
// ch가 닫힌 괄호인 경우
else{
// top()이 닫힌 괄호인 경우 && 형태가 다름
// top()이 닫힌 괄호인 경우 && 형태가 같음
// ==> 위의 2경우 모두 push(ch);
if(stk.top()==')'||stk.top()==']'){
stk.push(ch);
}
// top()이 열린 괄호인 경우
else{
// 형태가 다른 경우
if(stk.top()=='('&&ch==']'){
// break;
break;
}
else{
// 형태가 같은 경우
// pop();
stk.pop();
}
}
}
}
}
// stk이 비어있는 경우
if(stk.empty()){
// yes
ret+="yes\n";
}
// stk이 비어있지 않는 경우
else{
// no
ret+="no\n";
}
getline(cin,input);
}
printf("%s",ret.c_str());
return 0;
}
거의 대부분의 반례를 넣어도 통과가 됩니다. 어디서 잘못되었나요?
답변 1
0
안녕하세요 상준님 ㅎㅎ
일단 먼저 코드리뷰를 드리면
코드가 너무 복잡합니다.
1.중복되는 부분이 있습니다.
if(ch=='('||ch=='['){
// top()이 닫힌 괄호인 경우 && 형태가 다름
// top()이 닫힌 괄호인 경우 && 형태가 같음
// top()이 열린 괄호 && 형태가 다름
// top()이 열린 괄호 && 형태가 같음
// ==> 위의 4경우 모두 push(ch);
stk.push(ch);
}
예를 들어 이렇게 되어있는데
// top()이 닫힌 괄호인 경우 && 형태가 다름
// top()이 닫힌 괄호인 경우 && 형태가 같음
// ==> 위의 2경우 모두 push(ch);
if(stk.top()==')'||stk.top()==']'){
stk.push(ch);
}
그 다음에는 또 push를 하구요.
즉, 어차피 push를 할 건데 불필요한 분기처리가 있습니다.
else{
// no
ret+="no\n";
}
getline(cin,input);
마지막에 입력받는 부분도 처음에 입력받게 하면 깔끔하게 할 수 있습니다.
마지막으로 틀린 로직입니다.
if(stk.top()==')'||stk.top()==']'){
stk.push(ch);
}
// top()이 열린 괄호인 경우
else{
// 형태가 다른 경우
if(stk.top()=='('&&ch==']'){
// break;
break;
}
else{
// 형태가 같은 경우
// pop();
stk.pop();
}
}
상준님 로직은 만약 size가 있다면 -> 균형잡히지 않은 세상을 판단하는 것인데요.
top이 ) -> 라면 push를 해서 사이즈가 생기게 한다 -> 맞음
( 또는 [일 경우 -> ), ]이 만났을 때 제거해야 함. -> 이부분이 틀립니다.
if(stk.top() == '(' && ch == ')'){
stk.pop();
}else if(stk.top() == '[' && ch == ']'){
stk.pop();
}else{
break;
}
이렇게 고치셔야 합니다.
전체코드는 다음과 같습니다.
#include <bits/stdc++.h>
using namespace std;
int main(){
string input;
getline(cin,input);
string ret;
while(input!="."){
stack<char> stk;
for(int i=0;i<input.size();i++){
char ch=input.c_str()[i];
if(ch!='('&&ch!=')'&&ch!='['&&ch!=']') continue;
// stk이 비어있는 경우
if(stk.empty()){
// ch가 열린 괄호인 경우
if(ch=='('||ch=='['){
// push(ch);
stk.push(ch);
}
// ch가 닫힌 괄호인 경우
else{
// push(ch); break;
stk.push(ch);
break;
}
}
// stk이 비어있지 않은 경우
else{
// ch가 열린 괄호인 경우
if(ch=='('||ch=='['){
// top()이 닫힌 괄호인 경우 && 형태가 다름
// top()이 닫힌 괄호인 경우 && 형태가 같음
// top()이 열린 괄호 && 형태가 다름
// top()이 열린 괄호 && 형태가 같음
// ==> 위의 4경우 모두 push(ch);
stk.push(ch);
}
// ch가 닫힌 괄호인 경우
else{
// top()이 닫힌 괄호인 경우 && 형태가 다름
// top()이 닫힌 괄호인 경우 && 형태가 같음
// ==> 위의 2경우 모두 push(ch);
if(stk.top()==')'||stk.top()==']'){
stk.push(ch);
}
// top()이 열린 괄호인 경우
else{
// 형태가 다른 경우
if(stk.top() == '(' && ch == ')'){
stk.pop();
}else if(stk.top() == '[' && ch == ']'){
stk.pop();
}else{
break;
}
}
}
}
}
// stk이 비어있는 경우
if(stk.empty()){
// yes
ret+="yes\n";
}
// stk이 비어있지 않는 경우
else{
// no
ret+="no\n";
}
getline(cin,input);
}
printf("%s",ret.c_str());
return 0;
}
또 질문 있으시면 언제든지 질문 부탁드립니다.
좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)
감사합니다.
강사 큰돌 올림.