4차산업혁명의 일꾼/Java&Spring웹개발과 서버 컴퓨터

Java 코딩테스트

르무엘 2023. 4. 27. 21:02

패스트캠퍼스 (Java) 코딩테스트 강의 2주차 백준 과제 단계별로 풀어보기

 

https://www.acmicpc.net/step

 

단계별로 풀어보기

단계별은 @jh05013님이 관리하고 계십니다. 단계제목설명정보총 문제내가 맞은 문제1입출력과 사칙연산입력, 출력과 사칙연산을 연습해 봅시다. Hello World!132조건문if 등의 조건문을 사용해 봅시다

www.acmicpc.net

 

 

 

코딩테스트 강의에서 백준의  과제를 내주신 1~5단계까지를 살펴봤습니다.

김현정 강사님께서는 CH.02 시간복잡도로 넘어가기 전에 백준의 1~5의 단계를 모두 해야

좀더 수월하게 뒤를 할수 있다고 하셨습니다.

 

하기 내용은 벨로그에 정리해놨습니다.

 

시리즈 | 백준 - iamipro.log

https://www.acmicpc.net/problem/10811 약 6시간 전

velog.io

 

1단계 - 입출력과 사칙연산

2단계 - 조건문

3단계 - 반복문

4단계 - 1차원 배열

5단계 - 문자열

 

열심히 문제를 풀고 있는데 풀다가 주변에서

BufferedReader를 쓰면 더 빨리 풀 수 있다고 했고

이미 맞춘사람 답안을 참고해 보라 했습니다.

 

과연 BufferedReader가 더 빨랐습니다.

빨랐다는건 메모리를 더 적게 쓰기 때문에

코드가 더 효율적이고 알고리즘이 결과적으로 효율적이라

Scanner보다 BufferedReader를 쓰는게 낫다는 말이 되었습니다.

 

처음 학원에서  Scanner부터 써서

BufferedReader를 잘 몰랐는데 이번 기회에 

BufferedReader클래스, 즉 BufferedReader에 대한 것을 알게 되어 조사를 해보았습니다.

 

https://www.acmicpc.net/step

 

단계별로 풀어보기

단계별은 @jh05013님이 관리하고 계십니다. 단계제목설명정보총 문제내가 맞은 문제1입출력과 사칙연산입력, 출력과 사칙연산을 연습해 봅시다. Hello World!132조건문if 등의 조건문을 사용해 봅시다

www.acmicpc.net

 

자바 I/O에서 BufferedReader를 사용하는게 Scanner 보다 빠르다.

왜냐하면 자바 자체가 UTF-16인코딩을 하기 때문에 BufferedReader가 Scanner  보다 빠르다.

https://velog.io/@roycewon/BufferedReader%EB%A5%BC-%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90

 

BufferedReader를 알고 쓰자

Java를 처음 시작하면서 입력을 받을 땐 항상 Scanner를 사용했다

velog.io

 

https://rlakuku-program.tistory.com/33

 

[Java] 빠른 입출력을 위한 BufferedReader, BufferedWriter, StringTokenizer, StringBuilder

BufferedReader / BufferedWriter BufferedReader와 BufferdWriter는 버퍼를 사용하여 읽기와 쓰기를 하는 함수이다. 버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달된다.

rlakuku-program.tistory.com

 

버퍼는(Buffer)는 데이터를 임시저장하는 공간으로 주로I/O 작업에서 발생하는 속도차이를 완화하기 위해 사용된다. 예를 들어 빠른 CPU와 느린 하드디스크 사이에서 데이터 전송을 진행할 때 속도차이를 줄이기 위해 버퍼를 사용한다. 버퍼는 일반적으로 순차적으로 데이터를 읽고 쓰는데 사용되며 FIFO(First In First Out)원칙을 따른다.

참고로  DB나 웹상에서 자주 등장하는 용어인 캐시(Cache)는 자주 쓰는 데이터를 빠르게 접근할 수 있는 공간에 저장하여 성능향상을 목적으로 하는 것이다. 저장된 데이터의 위치와 상태에 따라 캐시교체 알고리즘이 적용된다.

 

BufferedReader의 readLine()을 사용하면 데이터를 라인단위로 읽을 수 있다.(readLine()의 return값은 String으로 고정되기 때문에 String이 아닌 다른 타입으로 입력을  받으려면 형변환을 꼭 해줘야 한다. 

(BufferedWriter는 많은 양의 출력이 필요할 때 쓰면 좋다.)

 

비슷한 것으로 StringBuilder가 있는데 동기화를 지원하여 멀티스레드에 안전한 StringBuffer와 달리 String Builder는 동기화를 지원하지 않아 단일 쓰레드 환경에서 사용하는 것이 유리하다.

 

위의 과정에서  InputStream클래스는  System  클래스에 선언된 추상클래스이다.

바이트코드를 저장할 수 있는 스트림 데이터를 int로 정의했기 때문에 화면에 abc를 입력해도 a 에 해당하는 아스키코드 97만 출력된다.

 

byte로 배열로 각각 받아야만 abc 3개 하나씩 출력 가능한것을 볼 수 있다.

 

char로 하면 아스키코드값이 아닌 문자열로 나온다.

 

Scanner 는 아래와 같이 쓰는데 코드상으로는 입력이 간편하나 암튼 메모리는 더 잡아 먹는다.

 

 

 

저걸 풀면서 뭐 기본적인 자바로 로직을 짜더라도

상당히 깊이 있게 생각할 부분이 있다는 것을 알게 되었다.

BufferedReader를 쓰느냐 아니면 Scanner을 쓰느냐에 따라서

내부적으로 어떻게 동작하는지 알아야만 무엇이 더 효율적인지 알 수 있는 것이다.

 

어쨌건 그래서 계속 단계별로 풀어보고 있다.

또하나 알아야 하는 것들이 있는데

https://jhnyang.tistory.com/entry/JAVA-StringTokenizer-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%A1%9C-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B6%84%EB%A6%AC%ED%95%98%EA%B8%B0-split-%EB%B9%84%EA%B5%90

 

[JAVA 자바] StringTokenizer 클래스로 문자열 분리하기! split 비교.

안녕하세요 양햄찌 블로그 주인장입니다. 저번시간에는 split 함수를 이용해서 문자열을 나누는 방식을 알아봤는데요. 혹시 해당 포스팅이 궁금하신 분은 아래 링크를 참고해주세요 ▼ 자바 SPLIT

jhnyang.tistory.com

 

BufferedReader클래스를 Scanner대신에 쓰는게 속도면에서 더 빠르고 메모리를 더 적게 잡아먹는다는 것을 알았다면,

그것을 더 잘 활용하기 위해

StringTokenizer 클래스를 알아야 한다.

왜냐하면 알고리즘의 요건을 해결하기위해 라인단위로 읽으면서,

토큰화로 끊어서 하나씩 접근할 수 있습니다.,

 

문자열을 토큰화했으니,

입력문을 라인단위의 문자열을 다룰 수 있기에,

문제 해결을 하기 위한 필수 클래스 입니다.

(자 하기 참고 해보면 hello와 world를 공백단위로 끊어버립니다.)

 

자 이것을 하기와 같이 
@을 기준으로 끊으면

test 와 naver.com 이 분리되어 출력되는 것을 볼 수 있습니다.

문득 String을 사용하면서 split 메소드 와의 차이점도 궁금해지는데

StringTokenizer는 java.util의 클래스이고 , split는 String클래스의 메소드인 것 부터가 다릅니다.

 

흠.. 생각해보면 String으로 만든 것을 다룰때 split로 짜를때 많이썼는데요~!

 

둘의 차이점을 보면,

1. 가장 큰 차이는 결과 값부터 생각하면 StringTokenizer은 결과값이 문자열이라면, split 메소드는 결과값이 배열입니다.

 

StringTokenizer는 자체가 클래스라는 것인데, 

일단 배열에 담아 반환하는 split는 데이터를 바로바로 잘라서 반환하는 StringTokenizer보다 성능이 뒤쳐지네요.

 

2. 두번째 차이점으로 하기를 살펴보면 StringTokenizer은 문자또는 문자열을 구분한다면, split 메소드는 정규표현식으로 구분합니다.

 

3. 마지막으로는 StringTokenizer는 빈 문자열을 토큰으로 인식하지 않지만 , split는 빈 문자열을 토큰으로 인식하는 차이가 있습니다~!

 

 

자 그리고 그 다음으로 알아야 할 것은 

StringTokenizer로 입력값을 요리조리 분리해서(토큰화시켜) 다룰줄 알게 되었다면~!

 

다시 재결합 해야 하는 경우가 있겠죠?

그 때 등장하는 것이 StringBuilder과 StringBuffer 클래스인데,

멀티스레드 동기화가 가능한 StringBuffer 클래스는 좀더 복잡하니 잠시 차치하고,

간단한 StringBuilder로 간단하게 합쳐버립니다.

 

자 문자열 입력하고, 쪼개고 , 합치고 하는 것들을 알았다면,

 

이제 열심히  단계별 과제를 해봅니다~!

 

그냥 하기만 모해서 벨로그 블로그에 한 것들을 모아 놓기로 했습니다.

https://velog.io/@iamipro/series

 

iamipro (임명수) / 시리즈- velog

3개의 포스트·마지막 업데이트 2023년 4월 25일

velog.io

 

 

 

 

 

 

문자열에서는

 charAt(j) 메소드로 문자열의 문자 인덱스(j) 추출 추출

int T = Integer.parseInt(br.readLine()); // 테스트 케이스 개수

        for(int i=0;i<T;i++){
            String[]str =br.readLine().split(" ");
            int R = Integer.parseInt(str[0]); // 반복 횟수
            String S = str[1]; // 문자열

            for(int j=0;j<S.length();j++){
                for(int k=0;k<R;k++){
                    System.out.print(S.charAt(j));
                }
            }
            System.out.println();
        }

reverse()메소드로 거꾸로 만들기

new StringBuilder(st.nextToken()).reverse()

StringTokenizer 클래스에서 countTokens()메소드로 토큰세기

 StringTokenizer st = new StringTokenizer(br.readLine()," ");
        System.out.println(st.countTokens());

String클래스를 toCharArray()메소드로 char 배열로 만들기

 String digit = br.readLine();
        char[] arr = digit.toCharArray();

Character.isDigit( word ) => 숫자유무 확인

if( !Character.isDigit(arr[0]) ){
                System.out.println(String.valueOf(arr[0]) + String.valueOf(arr[l-1]));
            }

sort메소드로 sort(배열)  하면 배열이 오름차순된다.

 Arrays.sort(scores);

 

HashSet => 중복x

HashSet<Integer> h = new HashSet<Integer>();

 

Math.max(a,b) => a,b중에 큰수

Math.max(a, b)

 

이렇게 정리하면서 

문자열쪽이 메서드를 좀알아야 하고

강사님이 시키신 기본기를 마치네요~!

 

 

 

 

LIST