https://www.acmicpc.net/problem/1152
문제
> 영어 대소문자와 공백으로 이루어진 문자열이 주어진다.
> 이 문자열에는 몇 개의 단어가 있을까?
> 이를 구하는 프로그램을 작성하시오.
> 단, 한 단어가 여러 번 등장하면 등장한 횟수만큼 모두 세어야 한다.
접근
StringTokenizer는 입력을 공백 기준으로 분리해서 토큰으로 저장한다. 이를 사용하면 공백은 제거되고 단어들만 남는다.
문제해결
> StringTokenizer를 st로 선언해주고 입력받은 br에 대해 공백을 제거하고 토큰을 가진다.
> while문을 돌며 st에 있는 토큰을 하나씩 가져와 str에 저장한다.
> 저장이 되면 단어가 있다는 뜻이므로 cnt를 하나씩 누적한다.
> 토큰이 없으면, 즉 단어가 없으면 while문이 끝나므로 cnt를 출력해준다.
코드
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main
{
//1152번 단어의 개수
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int cnt = 0;
while(st.hasMoreTokens())
{
String str = st.nextToken();
cnt++;
}
System.out.println(cnt);
}
}

후기
while문의 조건으로 st.nextToken() != Null로 했을 때 오류가 났다. 알고보니 nextToken은 st에 있는 토큰을 하나 가져와 "소비"한다고 한다. 그래서 조건에서 이미 토큰을 써버리는 뒤에 str엔 제대로된 값이 전달되지 않던 것이다. 그래서 hasMoreToken을 쓰면 토큰이 있다면 참을 반환하는 기능을 사용했다.
근데 추가로 아직 StringTokenizer의 기능들을 잘 몰라 while문으로 처리했지만, 하고 나서 더 알아보니 그냥 st에는 이미 단어들이 들어있고 이를 st.countTokens() 해버리면 되는 문제였다.