[백준] 1152. 단어의 개수
: 자율 bronze 2
https://www.acmicpc.net/problem/1152
1152번: 단어의 개수
첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열
www.acmicpc.net
정답
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char* sent = malloc(sizeof(char) * 1000000);
int word = 0;
gets(sent);
char* ptr = strtok(sent, " ");
while (ptr != NULL) {
word++;
ptr = strtok(NULL, " ");
}
printf("%d", word);
free(sent);
return 0;
}
해설
: strtok 함수를 이용한다.
쉬운 듯하지만 자잘하게 조심할 부분이 몇 가지 있는 문제이다.
1. 문제의 특성상 총 3개의 헤더파일을 include해줘야 한다.
하나는 입출력을 위한 stdio.h, 다른 하나는 문자열을 토큰 단위로 분리하기 위한 string.h,
다른 하나는 동적 할당(malloc)을 위한 stdlib.h이다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
2. char타입 포인터를 선언하고 동적 할당으로 최대 크기를 받아준다.
최대 글자수가 영문 100만자이기 때문이다. char타입(1바이트)라 괜찮을 수도 있지만,
보통 100만단위까지 가면 스택 공간으로는 부족하기 때문에 동적할당으로 힙 공간을 활용하도록 해주는 것이 좋다.
입력 함수는 gets를 사용하도록 한다. 공백을 모두 포함하여 한 문장으로 받아야 하기 때문이다.
scanf는 스페이스가 들어가면 끊지만, gets는 개행 단위로 끊으므로 이 문제에 적합하다.
int main() {
char* sent = malloc(sizeof(char) * 1000000);
int word = 0;
gets(sent);
3. strtok 함수는 strtok(분리할 문자열 시작주소, 구분자) 형식으로 사용하는 함수이다.
이 문제에서는 공백 문자가 구분자가 되므로 공백 문자만 구분자로 기입해 준다.
한 번 사용하면 구분자가 나오는 부분까지 문자열의 토큰을 분리해 포인터에 담아 주며, 분리한 부분에 널 문자를 남긴다.
한 번 더 사용하면 바로 전에 남긴 널 문자가 있는 부분부터 다시 구분자가 나오는 부분까지를 포인터에 담아준다.
이런 식으로 while문 등을 활용하여 반복 사용해 주면 된다.
이 문제의 경우에는 단어수를 세어주면 되므로 분리할 때마다 횟수를 세어 주었다.
문장의 끝에 도달하면 포인터에 널 문자가 담기므로 이것을 조건식으로 삼는다.
분리가 끝나면 단어수를 출력값으로 내고, 문자열에 할당했던 공간을 꼭 해제해 준다.
char* ptr = strtok(sent, " ");
while (ptr != NULL) {
word++;
ptr = strtok(NULL, " ");
}
printf("%d", word);
free(sent);
return 0;
}