[백준] 1152번: 단어의 개수
1152번: 단어의 개수
첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열
www.acmicpc.net
풀이
import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int wordCnt = 0;
while (st.hasMoreTokens()) {
st.nextToken();
++wordCnt;
}
bw.write(wordCnt + "");
br.close();
bw.flush();
bw.close();
}
}
처음에는 StringTokenizer를 사용하지 않았다. br.readLine()을 통해 문자열을 통째로 받아온 뒤 split(" ") 메서드를 사용하였는데, 입력받은 문자열 앞 뒤로 공백이 존재할 수 있으므로 이러한 경우 실제 단어 개수보다 +1 결과가 나왔다.
공백을 기준으로 나누어 가진 토큰의 개수는 단어의 개수와 일치하기 때문에 StringTokenizer를 사용하여 토큰 개수를 세었다.
정답 처리는 되었지만 308ms가 걸리므로 시간을 줄여보기로 했다.
System.in.read()를 사용하여 문자를 읽어오면 읽는 시간을 줄일 수 있다.
단어의 개수를 세는 것이니 공백의 개수만 세고 +1을 한 값을 반환하면 된다. 여기서 한 가지 문제는 문자열 앞 뒤로도 공백이 들어올 수 있다는 것이다. 이러한 경우 앞서 말했던 방식으로 계산하면 실제 문장 내 단어 개수보다 +1 한 값이 나오게 된다.
따라서 이전 문자 값과 비교하여 단어 개수를 세어줄 것이다.
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int wordCnt = 1;
int ch;
int backCh = ' ';
while (true) {
ch = System.in.read();
if (ch == '\n') {
if (backCh == ' ') --wordCnt;
break;
}
if (ch == ' ' && backCh != ' ') ++wordCnt;
backCh = ch;
}
bw.write(wordCnt + "");
br.close();
bw.flush();
bw.close();
}
}
이전 문자 값은 backCh 변수에 저장한다. 문자열이 공백으로 시작할 수 있으므로 backCh도 공백 값을 저장하여 선언한다.
현재 들어오는 값(ch)이 공백인 경우 wordCnt를 1 증가한다. 그리고 개행을 만나면 반복문을 종료한다.
개행을 받았을 때 이전 값이 공백 값이라면 문자열 제일 마지막에 공백이 존재한다는 것이니 1 증가시켜준 wordCnt 값을 1 감소시킨다.
속도는 156ms로 StringTokenizer를 사용한 코드보다 훨씬 빠르다.
[백준] 1152번: 단어의 개수
1152번: 단어의 개수
첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열
www.acmicpc.net
풀이
import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int wordCnt = 0;
while (st.hasMoreTokens()) {
st.nextToken();
++wordCnt;
}
bw.write(wordCnt + "");
br.close();
bw.flush();
bw.close();
}
}
처음에는 StringTokenizer를 사용하지 않았다. br.readLine()을 통해 문자열을 통째로 받아온 뒤 split(" ") 메서드를 사용하였는데, 입력받은 문자열 앞 뒤로 공백이 존재할 수 있으므로 이러한 경우 실제 단어 개수보다 +1 결과가 나왔다.
공백을 기준으로 나누어 가진 토큰의 개수는 단어의 개수와 일치하기 때문에 StringTokenizer를 사용하여 토큰 개수를 세었다.
정답 처리는 되었지만 308ms가 걸리므로 시간을 줄여보기로 했다.
System.in.read()를 사용하여 문자를 읽어오면 읽는 시간을 줄일 수 있다.
단어의 개수를 세는 것이니 공백의 개수만 세고 +1을 한 값을 반환하면 된다. 여기서 한 가지 문제는 문자열 앞 뒤로도 공백이 들어올 수 있다는 것이다. 이러한 경우 앞서 말했던 방식으로 계산하면 실제 문장 내 단어 개수보다 +1 한 값이 나오게 된다.
따라서 이전 문자 값과 비교하여 단어 개수를 세어줄 것이다.
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int wordCnt = 1;
int ch;
int backCh = ' ';
while (true) {
ch = System.in.read();
if (ch == '\n') {
if (backCh == ' ') --wordCnt;
break;
}
if (ch == ' ' && backCh != ' ') ++wordCnt;
backCh = ch;
}
bw.write(wordCnt + "");
br.close();
bw.flush();
bw.close();
}
}
이전 문자 값은 backCh 변수에 저장한다. 문자열이 공백으로 시작할 수 있으므로 backCh도 공백 값을 저장하여 선언한다.
현재 들어오는 값(ch)이 공백인 경우 wordCnt를 1 증가한다. 그리고 개행을 만나면 반복문을 종료한다.
개행을 받았을 때 이전 값이 공백 값이라면 문자열 제일 마지막에 공백이 존재한다는 것이니 1 증가시켜준 wordCnt 값을 1 감소시킨다.
속도는 156ms로 StringTokenizer를 사용한 코드보다 훨씬 빠르다.