이 문제를 본순간 공백을 이용한 형변환 for문 if문등이 떠올랐고 코드도 쉽게 완성했다. 쉬운데 왜 정답률이 낮을까 생각했는데.. 결정적으로 해결할 수 없던 문제가 있다. 바로 '공백'만 입력되었을때, 이를 걸러내기가 힘들다는것 걸러내기위한 코드를 작성한다쳐도 코드가 이뻐지지않는게 딜레마였다. 그치만 몇몇 클래스를 이용하면 굉장히 간단하게, 이쁘게 단어갯수를 셀 수 있는 코드를 짤 수 있었던것이다.
1) StringTokenizer - 입력 Scanner
StringTokenizer class 사용법
StringTokenizer sc = new StringTokenizer("abc def ghi"," ");
System.out.println(sc.countTokens());
실행결과 : 3 (문자의 개수)
문자열 "abc def ghi" 를 " "(공백)마다 잘라서 토큰화 시켜준다. countToken()은 토큰의 개수를 반환한다.
Answer
import java.util.Scanner;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String S = in.nextLine();
in.close();
StringTokenizer st = new StringTokenizer(S," ");
//StringTokenizer 클래스 선언 참조변수 S에 저장된 주소를 타고
//주소에 Scanner로 입력받아 저장된 문자열을 "(단위)"로 해당문제는 공백을 단위로 잘라 token화 한다.
System.out.println(st.countTokens());
//Token의 갯수를 세어 반환한다.
}
}
2) StringTokenizer - 입력 BufferedReader
1번과 똑같지만 이번엔 Scanner로 받는것이 아닌 BufferReader로 문자열을 받아서 StringTokenizer로 잘라주자
1152번 문제의 솔루션을 찾던중 Scanner와 BufferedReader 로 입력받는 두가지 케이스를 발견하고나서 스스로도 궁금증이 생겼다 둘이 무언가 차이가 있으니 2가지의 입력법이 있는것 아니겠는가? 백준을 풀면서 발견한 새로운 클래스도 공부했으니 두가지의 차이점에 대해서 가볍게 공부해보려한다.
● Scanner vs BufferedReader
3가지 관점에서 둘의 차이를 비교해 보자
2-a) 언제 데이터를 전송하는가?
Scanner는 입력과 동시에 값을 사용자에게 바로바로 전송해주기 때문에 전송 처리시간이 매번 소요된다 따라서 이 과정에서 시간을 상당히 잡아먹는다. 이와는 달리 BufferedReader는 입력시 Buffer에 저장후 Buffer가 꽉 차거나 Enter같은 개행문자를 만나면 데이터를 전송한다. 따라서 일거리를 받을때마다 움직이는 Scanner와 달리 일이 어느정도 모인후 한번에 처리하는 BufferedReader가 데이터 전송속도에서 좀 더 우위에 있다고 할 수 있다. 참고로 Scanner는 스페이스바와 엔터를 경계로 입력값의 경계를 나눈다.
2-b) 데이터 형변환
Scanner는 입력과 동시에 데이터의 타입이 결정되어 별도의 형변환이 필요없는 반면, BufferedReader는 입력을 줄 단위로 받기 때문에 모든 입력데이터를 String으로 인식한다 따라서 별도의 형변환이 필요하다.
2-c) 예외처리
BufferedReader는 예외처리를 해주어야한다. throw문이나 try-catch문을 이용하여 꼭 예외처리를 해주어야한다. Scanner는 필요없다.
여기까지 보면 BufferedReader는 속도 외에는 Scanner보다 이점이 별로 없어보인다 그럼에도 불구하고 사용되는 이유는 바로 BufferReader는 멀티 쓰레드에 안전하고, Scanner는 안전하지 않기 때문이다.
(이에 관해서는 나중에 예외처리와 스레드를 배우고 추가해보는걸로 하겠다.)
Answer
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class B1152_2 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//BufferedReader 객체 생성
String str = br.readLine(); //readLine()을 통하여 입력을받고, 반환타입이 String이다.
StringTokenizer st = new StringTokenizer(str," ");//토큰화
System.out.print(st.countTokens());
}
}
'Java > BackJoon' 카테고리의 다른 글
[Bac|<joon>] 백준 1712 : 손익분기점 / 사용자입장 , 관건은 처리시간! (0) | 2021.04.27 |
---|---|
[Bac|<joon>] 백준 : 2839 : 설탕배달 (0) | 2021.04.27 |
[Bac|<joon>]백준 : 4344 :평균은 넘겠지 (1) | 2021.04.21 |