본문 바로가기
코딩테스트/백준

[C++/덱] BOJ 5430 AC

by Ssubini 2021. 6. 22.

https://www.acmicpc.net/problem/5430

 

5430번: AC

각 테스트 케이스에 대해서, 입력으로 주어진 정수 배열에 함수를 수행한 결과를 출력한다. 만약, 에러가 발생한 경우에는 error를 출력한다.

www.acmicpc.net

성공 코드

#include <iostream>
#include <deque>
#include <string>
#include <sstream>

using namespace std;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int t, n, error;
    string p, nums;
    bool rev;
    deque<string> cutNums;

    cin >> t;
    while(t--){
        cin >> p;
        cin >> n;
        cin >> nums;
        rev = false; // R 여부 초기화
        error = 0; // error 여부 초기화

// string nums 입력값 괄호 삭제 
        nums.erase(nums.begin()); 
        nums.erase(nums.end()-1);

// string nums 입력값 , 기준으로 split
        istringstream ss(nums);
        string stringBuffer;
        cutNums.clear();

        while(getline(ss,stringBuffer, ',')){
            cutNums.push_back(stringBuffer);
        }

// 'R'인 경우 => rev 여부 바꿔줌/ 'D'인 경우 => 크기 확인 후 0인 경우 error, 아닌경우 rev = true 일 때 pop_back, false 일 때 pop_front
        for(auto i : p){
            if(i == 'R' && rev == false){
                rev = true;
            }else if(i == 'R' && rev == true){
                rev = false;
            }else if(i == 'D'){
                if(cutNums.size() == 0) error = -1;
                else{
                    if(rev == false) cutNums.pop_front();
                    else cutNums.pop_back();
                }
            }
        }

        // 출력
        if(error == -1) cout << "error" << '\n'; 
        else if(cutNums.size() != 0){
            cout << '[';
            if(rev == false){ 
                cout << cutNums.front();
                cutNums.pop_front();
                for(auto i = cutNums.begin(); i < cutNums.end(); i++){
                    cout << "," << *i;
                }
            }else{
                cout << cutNums.back();
                cutNums.pop_back();
                for(auto i = cutNums.rbegin(); i < cutNums.rend(); i++){
                    cout << "," << *i;
                }
            }
            cout << ']' << '\n';
        }else if(cutNums.size() == 0){ // 'D' 없이 'R' 중 입력값 없는 경우 출력
            cout << "[]" << '\n';
        }
    }

}

 

C++에 익숙하지 않아 기본적인 String split 방법을 몰라 검색해 찾아보았다.

 

첫 번째 실패

#include <iostream>
#include <deque>
#include <string>
#include <sstream>

using namespace std;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int t, n;
    int check = 0;
    string p, nums;
    deque<string> cutNums;
    deque<string> newNums;
    cin >> t;

    while(t--){
        cin >> p;
        cin >> n;
        cin >> nums;

        nums.erase(nums.begin());
        nums.erase(nums.end()-1);

// 여기서부터
        istringstream ss(nums);
        string stringBuffer;
        cutNums.clear();

        while(getline(ss,stringBuffer, ',')){
            cutNums.push_back(stringBuffer);
        }
// 여기까지 string 몰랐다!! 다시봐라!!

        for(auto i : p){
            if(i == 'R'){
                newNums.clear();
                for(auto j = cutNums.begin(); j < cutNums.begin()+n; j++){
                    newNums.push_back(cutNums.back());
                    //cout << newNums.back() << ' ';
                    cutNums.pop_back();
                }
                cutNums = newNums;
            }else if(i == 'D'){
                if(cutNums.size()==0) check = -1; // error 구분
                else cutNums.pop_front();
            }
        }

        // 출력
        if(check == -1) cout << "error" << '\n';
        else{
            cout << "[" << cutNums[0];
            cutNums.pop_front();
            for(auto i = cutNums.begin(); i < cutNums.end(); i++){
                cout << "," << cutNums.front();
                cutNums.pop_front();
            }
            cout << "]" << '\n';
        }

        check = 0;
    }
}

cutNums의 사이즈가 0인 경우를 고려하지 못해 에러가 났다.

이유를 찾지못한 segfault 런타임 에러가 계속 났다.

 

두 번째 실패

cutNums의 사이즈가 0인 경우를 구별하기 쉽게 하고, 정순서 출력과 역순서 출력의 구분을 쉽게 하기위해 boolean 변수 rev를 둬서 새롭게 코드를 짰다.

하지만 답을 돌렸을 때 실패가 떴다.

#include <iostream>
#include <deque>
#include <string>
#include <sstream>
using namespace std;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t, n, error;
    string p, nums;
    bool rev;
    deque<string> cutNums;
    cin >> t;
    while(t--){
        cin >> p;
        cin >> n;
        cin >> nums;
        rev = false; // R 여부 초기화
        error = 0; // error 여부 초기화
// string nums 입력값 괄호 삭제 
        nums.erase(nums.begin()); 
        nums.erase(nums.end()-1);
// string nums 입력값 , 기준으로 split
        istringstream ss(nums);
        string stringBuffer;
        cutNums.clear();
        while(getline(ss,stringBuffer, ',')){
            cutNums.push_back(stringBuffer);
        }
// 'R'인 경우 => rev 여부 바꿔줌/ 'D'인 경우 => 크기 확인 후 0인 경우 error, 아닌경우 rev = true 일 때 pop_back, false 일 때 pop_front
        for(auto i : p){
            if(i == 'R' && rev == false){
                rev = true;
            }else if(i == 'R' && rev == true){
                rev = false;
            }else if(i == 'D'){
                if(cutNums.size() == 0) error = -1;
                else{
                    if(rev == false) cutNums.pop_front();
                    else cutNums.pop_back();
                }
            }
        }
        // 출력
        if(error == -1) cout << "error" << '\n'; 
        else if(cutNums.size() != 0){
            cout << '[';
            if(rev == false){ 
                cout << cutNums.front();
                cutNums.pop_front();
                for(auto i : cutNums){
                    cout << "," << i;
                    cutNums.pop_front();
                }
            }else{
                cout << cutNums.back();
                cutNums.pop_back();
                for(auto i = cutNums.begin(); i < cutNums.end(); i++){
                    cout << "," << cutNums.back();
                    cutNums.pop_back();
                }
            }
            cout << ']' << '\n';
        }else if(cutNums.size() == 0){ // 'D' 없이 'R' 중 입력값 없는 경우 출력
            cout << "[]" << '\n';
        }
    }
}

=> 질문방에 질문하여 해결

감사하게도 고수분께서 반례를 찾아 문제점을 지적해 주셨다.

마지막 cutNums.size() != 0이고 rev == true 인 경우 출력에서 pop_back()을 하며 출력하니 end()가 점점 다가와서 출력이 제대로 되지 않았다.

따라서 코드를 pop 하지 않고, 순서대로 순회 / 역순으로 순회 하며 프린트만 해주는 방식으로 바꾸었다.

begin() ~ end() 까지 순회

rbegin() ~ rend() 까지 역순으로 순회

이렇게 출력하니 문제가 해결 되었다.

'코딩테스트 > 백준' 카테고리의 다른 글

[Python] BOJ 10816 - 숫자 카드 2  (0) 2022.04.13
[Python] BOJ 1654 - 나무자르기  (0) 2022.04.13
[C++/큐] BOJ 2164 카드2  (0) 2021.06.15
[C++/큐] BOJ 10845 큐  (0) 2021.06.15
[C++/스택] BOJ 10773 제로  (0) 2021.06.11

댓글