문자열을 자르기 위해 지금까지는 StringTokenizer 클래스를 써왔는데... 백준을 풀다보면 split을 사용하는 사람들이 많았다.
split은java 뿐만 아니라 C, Python 등에도 있어 보다 친숙했다. 과연 둘중 어떤 방법이 적합할지 알아보았다.
- java.util에 포함된 클래스이다
- 결과값으로 문자열을 반환한다. (String)
- 구분자를 기준으로 문자열을 토큰으로 잘라낼 수 있다. 그러나 구분자로 단 한 문자만 사용할 수 있다.
- 빈 문자열은 토큰으로 인식하지 않는다.
구분자를 지정하지 않아도 스페이스, 탭, 줄바꿈 등 기본 구분자가 적용된다.
String input = br.readLine();
StringTokenizer st = new StringTokenizer(input);
a = st.nextToken(); // 문자열을 반환
- String 클래스에 속한 메소드이다.
- 결과값으로 문자열 배열을 반환한다. (String[])
- 구분자에 정규식을 적용할 수 있어, 복잡한 형태의 구분자를 사용할 수 있다.
- 빈 문자열도 하나의 문자열로 분리한다.
String[] st = 문자열.split(","); // ',' 기준으로 문자열 자르기 (문자열 배열을 반환)
// 메타문자를 구분자로 사용하려면 '\\' 붙이기
String[] st = 문자열.split("\\."); // '.' 기준으로 문자열 자르기
// 여러가지 구분자를 사용하려면 '|'으로 구분
String[] st = 문자열.split("@|,"); // '@' 또는 ',' 기준으로 문자열 자르기
Tokenizer와 split의 성능을 비교하는 글은 정말 많았다.
결론은 구분자를 어떤 형태로 하느냐에 따라 split이 더 빠를 때도, 느릴 때도 있다는 것. 성능을 비교한 블로그 참고
- 구분자가 복잡한 형태라면, 애초에 Tokenizer는 불가능하고 정규식을 사용할 수 있는 split()을 쓰자.
- 그러나, 구분자가 문자 하나이면 Tokenizer가 더 빠를 가능성이 높다.
- 그러나, 공식문서에서 StringTokenizer가 legacy 클래스라며 .split()을 권고한다...(⊙ˍ⊙) 그러니 실제 프로젝트라면 신중히 고민할 필요가 있다.
하지만 코딩테스트 용은 괜찮을 듯 하다.
- 분리한 문자열을 배열에 저장할 필요 없이, 단순히 출력만 할 때에는 빠른 Tokenizer을 쓰자! (split은 배열에 저장했다가 꺼내야 하니)
- 각 문자열을 저장해야 한다면 split()을 쓰자!
입력받는 부분만 비교해보자. 문제 링크
for(int i=1; i<=N; i++) {
String input = br.readLine();
StringTokenizer st = new StringTokenizer(input);
amount = Integer.parseInt(st.nextToken());
quantity = Integer.parseInt(st.nextToken());
subAmount += amount * quantity;
}
for(int i=1; i<=N; i++) {
String[] input = br.readLine().split(" "); // 공백 기준 자르기
amount = Integer.parseInt(input[0]);
quantity = Integer.parseInt(input[1]);
subAmount += amount * quantity;
}
속도는 split()을 사용할 때가 조금 느려진 결과이다!