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 |
댓글