문제

8진수 2진수 백준 1212번


리뷰

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;
} 
728x90

'알고리즘 > 백준' 카테고리의 다른 글

숨바꼭질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

+ Recent posts