개발자는 기록이 답이다

[백준/BOJ][Java][2908] 상수 본문

알고리즘/백준

[백준/BOJ][Java][2908] 상수

slow-walker 2023. 8. 24. 16:28

2023.08.21 - [Java] - Java, String의 constant pool과 Heap의 차이

 

Java, String의 constant pool과 Heap의 차이

Java String 문자열? 순서를 가진 문자들의 집합 “쌍따옴표를 통해 나타낼 수 있음” 글자, 단어, 문장, 문서 등 문자로 구성된 자료형 // 기본 자료형 int var_integer = 10; double var_real - 3.141592; char var_ch

strong-park.tistory.com


 

 

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

 

2908번: 상수

상근이의 동생 상수는 수학을 정말 못한다. 상수는 숫자를 읽는데 문제가 있다. 이렇게 수학을 못하는 상수를 위해서 상근이는 수의 크기를 비교하는 문제를 내주었다. 상근이는 세 자리 수 두

www.acmicpc.net

내가 푼 풀이

공백을 기준으로 문자열을 나눈뒤, for문을 통해서 뒤에서부터 문자열을 저정해서 최댓값을 구하려고 했다.

성능차이는 없다고 하는데, Integer.parseInt() (80ms) 보다 Integer.valueOf() (76ms)  가 속도가 조금 더 빨랐다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();

        String[] splitStr = str.split(" ");

        int max = 0;
        for (int i = 0; i < splitStr.length; i++) {
            String temp = "";
            for (int j = splitStr[i].length() - 1; j >= 0; j--) {
                temp += String.valueOf(splitStr[i].charAt(j));
            }
            if (max < Integer.valueOf(temp))
                max = Integer.valueOf(temp);
        }
        System.out.println(max);
    }
}

 

메모리 시간 언어 코드 길이
11516MB 76ms Java8 730B

 

 

하지만 아래 사진으로 봤을때 valueOf를 사용하면 불필요한 언박싱을 하고 있다. new Integer(Integer.parseInt(s))이다.

라고 나와서..다음번에는 parseInt를 사용해야겠다.

더보기

Integer.valueOf() 메서드는 내부적으로 Integer.parseInt()를 호출하여 값의 변환을 수행하지만, 이때 valueOf() 메서드는 불필요한 객체 생성(박싱)이 추가로 발생할 수 있다는 것을 의미합니다. 그래서 단순한 값 변환 목적으로는 Integer.parseInt()를 사용하는 것이 더 효율적일 수 있다는 얘기입니다.

 

다른 사람 풀이 1

- StringTokenizer을 통해서 문자열을 쪼개준 뒤, 각 문자열의 인덱스값에 자릿수를 곱해서 푼 방식이다.

- for문 안에서 입력값을 하나씩 받아와서 계산한 뒤 배열에 넣어준다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	public static void main(String args[]) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());

		int[] num = new int[2];
		for (int i = 0; i < 2; i++) {
			String str = st.nextToken();
			num[i] = (int) (str.charAt(2) - '0') * 100 + (int) (str.charAt(1) - '0') * 10 + (int) (str.charAt(0) - '0');
		}
		System.out.print((num[0] > num[1]) ? num[0] : num[1]);
	}
}
메모리 시간 언어 코드 길이
11416MB 68ms Java8 612B

 

다른 사람 풀이 2

- 48을 빼는게 신기했다. 48은 '0'의 아스키코드라고 한다.

System.in.read()
메서드는 표준 입력(Standard Input)으로부터 바이트를 읽어들이는 함수입니다. 이 메서드는 읽어들인 바이트의 ASCII 값에 해당하는 정수를 반환합니다.

아스키 코드에서 숫자 '0'은 48의 ASCII 값이며, '1'은 49, '2'는 50, ..., '9'는 57입니다. 따라서 표준 입력으로부터 읽어들인 바이트가 숫자 문자에 해당하는 경우, 그 문자의 아스키 값을 가져오기 위해 48을 빼는 것입니다.

예를 들어, '5'라는 문자를 읽어들였다면 System.in.read() - 48을 계산하면 5가 됩니다. 이렇게 함으로써 문자를 숫자로 변환하여 사용할 수 있습니다.

 

- Math클래스의 max함수를 이용하면 간단하게 풀 수 있다는걸 알았다.

import java.io.IOException;


public class Main {
    public static void main(String[] args) throws IOException {
        int A = 0;
        int B = 0;

        A += System.in.read() - 48;
        A += (System.in.read() - 48) * 10;
        A += (System.in.read() - 48) * 100;
        System.in.read();
        B += System.in.read() - 48;
        B += (System.in.read() - 48) * 10;
        B += (System.in.read() - 48) * 100;

        System.out.println(Math.max(A, B));
    }
}
메모리 시간 언어 코드 길이
11428MB 68ms Java8 478B

 

응용 풀이

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int max = 0;
        for (int i = 0; i < 2; i++) {
            String s = st.nextToken();
            int temp = Integer.parseInt(String.valueOf(
                    (s.charAt(2) - '0') * 100 + (s.charAt(1) - '0') * 10 + (s.charAt(0) -'0')));
            if (max < temp)
                max = temp;
        }
        System.out.println(max);
    }
}
메모리 시간 언어 코드 길이
11524MB 76ms Java8 717B

 

 

참고 링크 : 

https://reakwon.tistory.com/90

 

[자바/JAVA] StringTokenizer를 이용해 문자열을 쪼개보자

StringTokenizer StringTokenizer 클래스는 문자열을 우리가 지정한 구분자로 문자열을 쪼개주는 클래스입니다. 그렇게 쪼개어진 문자열을 우리는 토큰(token)이라고 부릅니다. StringTokenizer를 사용하기 위

reakwon.tistory.com

https://m.blog.naver.com/sthwin/221000179980

 

Integer.parseInt() vs Integer.valueOf() 차이

자바에서 스트링을 숫자 값으로 변형할 때 Integer.parseInt() vs Integer.valueOf() ...

blog.naver.com

https://ssdragon.tistory.com/22

 

valueOf() 와 parseInt() 의 차이점

Integer 라는 래퍼클래스(Wrapper Class)가 가지고 있는 메서드들이다. 이 메서드 두 개는 String을 int로 바꿀수 있다. 하지만 차이점이라면 반환값에 있다. Integer.valueOf("10") 은 Integer 타입으로 반환하고,

ssdragon.tistory.com