C언어/BAEKJOON

[백준] 1152. 단어의 개수

너굴맨이해치움 2022. 9. 18. 04:25

: 자율 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;
}