백준에서 자바 사용

Bam·2024년 4월 6일
1

etc

목록 보기
9/9
post-custom-banner

Node.js를 사용하기 때문에 사전에 이런저런 준비가 필요했던 자바스크립트와는 다르게 자바는 딱히 설정할 것 없이 바로 사용할 수 있습니다.

그래서 유별난 팁은 아니지만 제가 개인적으로 사용하는 팁을 소개해볼까 합니다.


클래스 이름은 Main

이건 저만 쓰는 팁은 아니고 백준에서 이렇게 쓰세요~하고 정한 것 입니다. 자바로 처음할 때 public static void main을 바로 쓰면 되나? 클래스를 작성해야하나?하고 당황했었는데 클래스부터 작성하는 것이 맞았고, 이름은 Main으로 하도록 되어있었습니다.

public class Main {
	public static void main(String[] args) {
    	//솔루션 코드 작성
    }
}

IDE에서 작성하기

백준 사이트의 제출란은 단순히 텍스트를 입력할 수 있는 기능만을 지원하고 있고, 자바 언어 코드가 다른 언어들에 비하면 타이핑할 내용이 많은 편에 속하는 언어이기 때문에 코딩 과정에서 오탈자 등으로 인한 오류가 발생할 확률이 높습니다. (아님말고)

그래서 저는 인텔리제이에서 작성한 후 복사 붙여넣기 해서 사용하고 있습니다. 자동 완성 외에도 특정 메소드의 기능을 볼 수도 있고 하기 때문에...

물론 IDE 사용을 불허하는 코딩 테스트도 몇 번 있었기 때문에 너무 자동 완성에만 기대는 것도 좋다고는 못하겠지만, 당장 연습을 위한 문제풀이에선 효율을 위해서 IDE를 사용하도록 합시다.


솔루션과 main 메소드 분리하기

개인적으로 main 메소드는 솔루션 메소드를 호출하는 부분만을 작성하고 솔루션을 위한 메소드를 따로 작성하는 것을 선호합니다.

그래서 다음 코드와 같은 템플릿을 복사해뒀다가 solution에 풀이 코드를 적습니다. 필요하다면 리턴값이나 매개변수를 조금조금씩 수정해줘도 되고요.

public class Main {
    public static void solution() {
        //솔루션 코드 작성
    }
    
    public static void main(String[] args) {
        solution();
    }
}

import java.util.*; 넣기

코딩 테스트 풀이에 필요한 대부분의 메소드는 java.util 패키지에 존재하고 있습니다. 그래서 내가 어떤 클래스의 메소드를 사용할 예정이다!라고 생각이 든다면 import java.util.*; 선언을 최상단에 박아둡니다.

물론 IDE를 사용한다면 IDE가 자동으로 import를 해주기 때문에 이런 걱정은 없겠지만, 만약 IDE 사용이 불가능한 상황이라면 일단 선언해 두시고 작성을 시작하는 것을 권장드립니다.

마찬가지로 다음에 소개드릴 BufferedReader, BufferedWriter 클래스는 java.io 패키지에 있기 때문에 두 클래스를 사용한다면 java.io.*도 import 하고 시작하는 것을 권장드립니다.

import java.util.*;
import java.io.*;

public class Main {
    public static void solution() {
        //솔루션 코드 작성
    }
    
    public static void main(String[] args) {
        solution();
    }
}

입출력 BufferedReader/BufferedWriter

BufferedReader

자바 기초를 공부할 때 키보드로부터 입력은 Scanner 클래스를 많이 사용했었습니다. 하지만 시간 제한이 있는 코딩 테스트의 특성상 가끔씩은 시간 초과에 대해 관리할 필요가 있기도 합니다.

백준 사이트에서 백준님이 여러 언어들의 입력 속도를 비교한 표가 있는데요. 이 표를 보시면 BufferedReaderScanner의 입력 속도 차이가 유의미하게 나온다는 것을 볼 수 있습니다.

대부분의 코딩테스트 문제는 String 아니면 int를 받기 때문에 두 타입을 받는 방법에 대해서 알아보겠습니다.

String 입력받기

BufferedReader는 기본적으로 String으로 데이터를 읽습니다. 따라서 별다른 가공 없이 입력을 받아내면 됩니다.

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

public class Main {
    public static void solution() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        
        //솔루션 코드 작성
        
        br.close();
    }

    public static void main(String[] args) throws IOException {
        solution();
    }
}

int 입력받기

소제목은 int 입력받기지만 받는 데이터에 따라서 float, double, long 등 상황에 맞춰 적용하시면 됩니다.

int 형 등의 타입을 받을 때는 형변환이 필요합니다.

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

public class Main {
    public static void solution() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        br.close();
    }

    public static void main(String[] args) throws IOException {
        solution();
    }
}

StringTokenizer

위 예제들은 문자열 하나, 숫자 하나를 입력받는 상황이었습니다.

백준의 문제들 중에서는 다음과 같이 한 줄에 여러 데이터가 입력받는 경우가 종종 있는데요. 이때 split()보다 StringTokenizer 클래스를 이용해서 각 데이터를 분할하고 취득하는 것이 빠릅니다.

apple banana lemon

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

public class Main {
    public static void solution() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        while (st.hasMoreTokens()) {
            System.out.println(st.nextToken());
            //분할된 문자열 데이터를 가공할 코드
        }

        br.close();
    }

    public static void main(String[] args) throws IOException {
        solution();
    }
}

위 코드는 분할 후 출력을 보여주기 위한 예제이기 때문에 while 부분을 입맛에 따라 수정해서 사용하시면 됩니다.

위 코드는 String 타입을 받는 코드인데요. int형을 받고자 한다면 아래와 같이 수정합니다.

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

public class Main {
    public static void solution() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        while (st.hasMoreTokens()) {
            int n = Integer.parseInt(st.nextToken());
            //n을 이용해 가공하는 코드
        }

        br.close();
    }

    public static void main(String[] args) throws IOException {
        solution();
    }
}

BufferedWriter

마찬가지로 System.out.print()보다 BufferedWriter 클래스를 이용한 출력이 더 빠릅니다.

String 출력하기

import java.io.*;

public class Main {
    public static void solution() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        String str = br.readLine();
        
        bw.write(str);

        bw.flush();
        bw.close();
        br.close();
    }

    public static void main(String[] args) throws IOException {
        solution();
    }
}

int 출력하기

import java.io.*;

public class Main {
    public static void solution() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int n = Integer.parseInt(br.readLine());

        bw.write(String.valueOf(n));

        bw.flush();
        bw.close();
        br.close();
    }

    public static void main(String[] args) throws IOException {
        solution();
    }
}


이때 write()는 출력할 값이 String이 아니라면 다시 String으로 변환해주어야합니다.

String.valueOf()+""는 둘 다 String 타입의 변환을 수행합니다. 전자는 가독성이 좋지만 여러 변환 과정이 있어서 속도가 느리고, +""는 가독성은 떨어지지만 속도가 좀 더 빠릅니다. 따라서 코딩 테스트에서는 +""를 사용하는 것을 권장드립니다.
https://stackoverflow.com/questions/7752347/string-valueof-vs-concatenation-with-empty-string


최종 템플릿

위 사항들에 따라 완성된 최종 기본 템플릿은 다음과 같습니다.

import java.util.*;
import java.io.*;

public class Main {
    public static void solution() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        //솔루션 코드 작성

        bw.flush();
        bw.close();
        br.close();
    }

    public static void main(String[] args) throws IOException {
        solution();
    }
}

위 코드를 문제 상황에 맞춰서 지우거나 추가하고 데이터 변환을 하면서 사용하시면 될 것 같습니다.


IDE의 디버그 기능 활용하기

현재 사용하고 있는 IDE인 인텔리제이 기준으로 설명되어있습니다.

문제를 풀다가 틀렸습니다.라는 문구가 나오면 아찔해집니다. 어디서 왜 틀렸는지 알려주지 않기 때문이죠.

이럴땐 IDE에서 제공하는 디버그 기능을 이용하면 코드를 순차적으로 돌면서 변수 값 등의 변화를 보여줍니다.위와 같은 코드에서 코드 라인 번호를 클릭하면 다음과 같이 빨간줄이 쳐지면서 중단점(breakpoint)가 생성됩니다.우클릭을 통해 Debug 실행을 하게 되면, 코드를 똑같이 run하다가 중단점에서 일시 정지가 되면서 코드의 상황을 한 줄 씩 또는 더 세세하게 확인할 수 있습니다. F8을 이용하거나 Step Over를 눌러서 한 줄 씩 이동하면 코드를 진행하면서 변화를 확인할 수 있습니다.이렇게 각 변수의 값을 확인하면서 현재 진행 위치까지 확인할 수 있는 아주 유용한 기능입니다.


당장 사용하고있는 팁들은 적긴했는데 나중에 팁이 추가적으로 생기면 추가하도록 하겠습니다.

post-custom-banner

0개의 댓글