문제
리뷰
8진수 한 자리는 2진수 세 자리로 표현할 수 있다.
예를 들어, 8진수 7은 2진수로 111 이다. 111은 곧 4+2+1 == 7 이기 때문이다.
8진수 1 자리가 들어왔을 때, 2진수 3자리로 바꿔서 스택에 넣어줬다.
가장 작은 자리수 부터 계산하니까. 스택에 넣은다음에 출력할 때는 올바른 순서로 나오기 때문에 스택을 선택했다.
8진수를 2로 나눈 나머지를 스택에 저장한다. 이 때, 나눗셈을 3번 한다.
처음에는 틀렸는데, 질문게시판을 보니까 0을 넣으면 0이 나와야 한다는 댓글을 봤다.
내코드에서는 0넣으면 아무것도 출력이 안됬었다.
이유는 스택에 001100 가 들어가 있다면, 1100 으로 출력하기 위해서였다. 0으로 시작하는 이진수는 없기 때문이다.
처음에는 스택의 top이 0이고, flag 가 false 라면 pop만 하고, 출력하지 않았다.
처음 1이 나올때 부터, flag를 true로 바꿔줘서, top 출력과 pop 둘 다 하도록 했다.
bool flag= false;
while(!answer.empty()){ // 스택 출력
if(answer.top() == 0 && flag == false){
answer.pop();
continue;
}else{
flag = true;
}
cout << answer.top();
answer.pop();
}
입력이 8진수 0이라면, 이진수도 답이 0이 나와야 하니까
while문의 첫번째 if문 조건을 수정했다.
bool flag= false;
while(!answer.empty()){ // 스택 출력
if(answer.top() == 0 && flag == false && answer.size() != 1){
answer.pop();
continue;
}else{
flag = true;
}
cout << answer.top();
answer.pop();
}
맞은 코드 1 (내가 짠 코드)
#include <iostream>
#include <string>
#include <cstring> // strcpy()
#include <stack>
using namespace std;
string st;
char N[333335];
stack<int> answer;
int main(void){
cin >> st;
strcpy(N, st.c_str()); // string을 char 배열로 복사
int len = st.length(); // 8진수의 길이
for(int i = len-1; i >= 0 ; i--){
int temp = N[i]-48;
if(temp == 0){
answer.push(0); answer.push(0); answer.push(0);
continue;
}
for(int j = 0; j < 3; j++){ // 0이 아니라면, 2로 나눈 나머지를 stack에 push
answer.push(temp % 2);
temp /= 2;
}
}
bool flag= false;
while(!answer.empty()){ // 스택 출력
if(answer.top() == 0 && flag == false && answer.size() != 1){
answer.pop();
continue;
}else{
flag = true;
}
cout << answer.top();
answer.pop();
}
return 0;
}
내 코드가 어수선 하다는 느낌이 들었다. 다른 분들 코드를 찾아 보고 배웠다.
8진수를 2진수로 나타낼 수 있는 8가지 문자열을 미리 배열에 저장해두고 활용하는 방식이다.
first는 첫 숫자가 0이 나오면 안되니까 만들어 둔 배열이다. 0으로 시작하는 이진수는 없기 때문이다.
string first[8] = {"0", "1", "10", "11", "100", "101", "110", "111"};
string other[8] = {"000", "001", "010", "011", "100", "101", "110", "111"};
string st;
cin >> st;
cout << first[st[0] - '0'] ; // 문자로 된 숫자 하나에서 '0' 을 빼주면 숫자가 나온다
first [ st[0] - '0' ] 이게 뭐지 싶었는데.
예를 들어, st[0] 이 문자 '3' 이라면, 문자 3에서 문자 0을 뺴야 숫자 3을 얻을 수 있다.
// st [0] == '3'
first [ '3' - '0' ] = first [3]
과 같다.
other[st[i] - '0']; 도 같은 구조다.
// st[0] 이 문자 5라면 (8진수로 5를 받았다면,)
other[ '5'-'0' ] == other [5] 가 된다. 이렇게 8진수를 2진수로 변환한다.
가독성도 좋고 아주 배우고 싶은 코드여서 정리한다.
맞은 코드 2
#include <iostream>
#include <string>
using namespace std;
string first[8] = {"0", "1", "10", "11", "100", "101", "110", "111"};
string other[8] = {"000", "001", "010", "011", "100", "101", "110", "111"};
int main(void){
string st;
cin >> st;
cout << first[st[0] - '0'] ; // 문자로 된 숫자 하나에서 '0' 을 빼주면 숫자가 나온다
for(int i = 1; i < st.size(); i++){
cout << other[st[i] - '0'];
}
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
숨바꼭질6 백준 17087번 c++ (0) | 2020.09.19 |
---|---|
링크와 스타트 백준 15661번 c++ (0) | 2020.09.17 |
2진수 8진수 백준 1373번 (0) | 2020.09.15 |
진법변환 백준 2745번 (0) | 2020.09.15 |
진법변환2 백준 11005번 c++ (0) | 2020.09.15 |