본문 바로가기
Algorithm/BOJ

[BOJ]1373번: 2진수 8진수(java, c++)

by HBGB 2019. 9. 23.

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

 

1373번: 2진수 8진수

첫째 줄에 2진수가 주어진다. 주어지는 수의 길이는 1,000,000을 넘지 않는다.

www.acmicpc.net

 

 

방법1: 앞에서부터, 문자열의 char의 int값을 이용해서 연산하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.io.*;
 
public class Main {
    static String BinaryNum;
 
    public static void main(String[] args) {
 
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringBuilder sb = new StringBuilder();
 
            BinaryNum = br.readLine();
 
            int iStart = 0;
            int inputLength = BinaryNum.length();
            int iLeft = inputLength % 3;
 
            if (iLeft > 0) {
                sb.append(oneOctUnit(0, iLeft));
                iStart += iLeft;
            }
            
            for (int i = iStart; i < inputLength; i += 3) {
                sb.append(oneOctUnit(i, 3));
            }
 
            System.out.println(sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static int oneOctUnit(int i, int length) {
        int iOctUnit = 0;
 
        for (int k = 0; k < length; k++) {
            iOctUnit += (BinaryNum.charAt(i + k) - '0'* (Math.pow(2length - 1 - k));
        }
        return iOctUnit;
    }
}
Colored by Color Scripter

 

c++소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <cmath>
 
using namespace std;
 
// 2진수 -> 8진수. string을 받아서 처리한다.
int binary_to_octal(const string &str)
{
    int octal = 0;
    for (int i = 0; i < str.size(); i++)
    {
        if (str[i] == '1')
        {
            octal += pow(2, str.size() - i - 1);
        }
    }
    return octal;
}
 
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    string input;
    cin >> input;
 
    // 입력값 길이가 3으로 나누어 떨어지지 않으면, 
    // 초기에 나머지 길이만큼만 계산.
    int mod = input.size() % 3;
    if (mod > 0)
    {
        cout << binary_to_octal(input.substr(0, mod));
    }
 
    // 그 뒤에는 3자리씩 잘라서 계산
    for (int i = mod; i < input.size(); i += 3)
    {
        cout << binary_to_octal(input.substr(i, 3));
    }
 
    return 0;
}
Colored by Color Scripter

 

 

방법2: 뒤에서부터, 문자열을 Integer 파싱하여 연산하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.io.*;
import java.util.Stack;
 
public class Main {
    public static void main(String[] args) {
 
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringBuilder sb = new StringBuilder();
            Stack<Integer> stack = new Stack<Integer>();
    
            String[] arrNums = br.readLine().split("");
            
            for (int i = arrNums.length - 1; i >= 0; i -= 3) {
                
                int iOctUnit = 0;
                for (int k = 0; k < 3 && i - k >= 0; k++) {
                    iOctUnit += Integer.parseInt(arrNums[i - k]) * (Math.pow(2, k));
                }
                stack.push(iOctUnit);
            }
            
            while (!stack.isEmpty()) {
                sb.append(stack.pop());
            }
            System.out.println(sb.toString());
            
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Colored by Color Scripter

 

 

방법1: 앞에서부터, 문자열의 char의 int값을 이용해서 연산하기

방법2: 뒤에서부터, 문자열을 Integer 파싱하여 연산하기

 

방법1이 방법2보다 3배가 빨랐다!

 

 

TIP1

주어지는 수의 길이는 1,000,000을 넘지 않는다.

수가 너무 크기 때문에, 실제 자료형에 저장을 할수는 없고 문자열로 받는다. 

 

 

 

TIP2

앞에서부터 연산하자!

 

수학을 계산하는 것처럼 뒤에서부터 했는데,

그러면 for문을 불필요하게 한번 더 돌리게 되고,

stack도 오직 순서를 바꾸기 위해 사용하게 된다.

 

 

TIP3

문자열의 char의 int값을 이용하자

(BinaryNum.charAt(i + k) - '0')

 

수를 문자열로 받았으므로,

각 수는 사실 '0' ~ '9'와 같은 문자이며, 아스키코드로는 48 ~ 57에 해당한다. 

 

이때, '9' - '0' = 57 - 48 = 9 이다. 

Integer 파싱보다 훨씬 간편하다. 

 

 

 

댓글