본문 바로가기
⌨️CS-PS/백준_문자열

[Baekjoon/백준][1152][C/C++] 단어의 개수

by 미르의 블로그 2023. 2. 8.
728x90
반응형
『목차』
0. 개요

1. 문제
2. 풀이
3. 코드

0. 개요

구현, 문자열 문제. 문제에서 예외처리를 해주어야 하는 부분이 1가지 존재한다. 이 부분을 예외처리 해주지 않으면 100%에서 오답이 발생한다.

1. 문제

https://www.acmicpc.net/problem/1152

 

1152번: 단어의 개수

첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열

www.acmicpc.net

[문제]

영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열에는 몇 개의 단어가 있을까? 이를 구하는 프로그램을 작성하시오. 단, 한 단어가 여러 번 등장하면 등장한 횟수만큼 모두 세어야 한다.

[입력]

첫 줄에 영어 대소문자와 공백으로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 공백 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 문자열은 공백으로 시작하거나 끝날 수 있다.

[출력]

첫째 줄에 단어의 개수를 출력한다.

[예제 입력 1]

The Curious Case of Benjamin Button

[예제 출력 1]

6

[예제 입력 2]

 The first character is a blank

[예제 출력 2]

6

[예제 입력 3]

The last character is a blank 

[예제 출력 3]

6

2. 풀이

풀이를 시작하기 전에

fgets 함수를 이용하여 문제를 풀었다. 다만, fgets함수는 자신만의 독특한 특징이 있어, 이 부분을 짚고 넘어가야 함수를 이용할 때 헤매지 않는다. fgets 함수의 특징은 다음과 같다. (링크를 참조하거나, 아래쪽 글을 읽자.)

https://lumir.tistory.com/31

 

[C][header][stdio.h] fgets

fgets #include // C++ 의 경우 char* fgets(char* str, int num, FILE* stream); 특징 1. 개행(=newline)(='\n') 혹은 파일끝(=EOF)을 만날 때 까지, 해당 stream의 buffer에서 문자열을 읽어들인다. (개행(=newline)(='\n') 혹은 파

lumir.tistory.com

fgets 함수의 특징

1. 개행(=newline)(='\n') 혹은 파일끝(=EOF)을 만날 때까지, 해당 stream의 buffer에서 문자열을 읽어 들인다.

(개행(=newline)(='\n') 혹은 파일끝(=EOF)을 만나면, 입력이 종료된다.)

2. 문자열을 읽어 들인 후, 문자열 끝에 NULL(='\0')값이 자동으로 추가된다.

3. fgets는 gets와 달리, 개행(=newline)(='\n')이 포함된 채 저장된다.

문제풀이

2가지 방식으로 문제를 풀었다.

첫번째 풀이는, fgets함수를 통해 입력받은 '\n'을 지우고 푸는 풀이.

두번째 풀이는, fgets함수를 통해 입력받은 '\n'을 지우지 않고 푸는 풀이이다.

'\n'을 지우는 부분을 제외하면 두 풀이는 거의 일치한다. 단, '\n'의 유무로 인하여, 문자열의 길이를 세는 strlen(str) 부분에서 차이가 발생한다.

 

/* 배열 str에 문장을 입력 받음. */

배열에 입력으로 주어진 문자열을 입력받는다. 이때, '\n'과 '\0'이 배열에 포함된다.

 

/* 마지막 문자가 개행(=\n)일 경우, 개행문자 삭제 */

배열에서 개행문자를 삭제한다.

 

/* 문자 사이 공백 세기 */ & /* 문장에 공백 1개만 나오는 경우는 예외처리. ex. " " */

일반적인 경우, '(문자열의 처음과 마지막에 존재하는 공백을 제외한 나머지 공백의 개수) + 1' 값이 단어의 개수이다.

단, 문장에 공백이 1개만 나오는 경우는 예외처리를 해주어야 한다. 이 경우는 단어의 개수가 0개이기 때문이다.

3. 코드

#pragma warning (disable:4996)
#include <stdio.h>
#include <string.h>

#define MAX 1000002 //'\n'과 '\0'고려.

int main(int argc, char* argv[]) {
	/* 배열 str에 문장 입력 받음. */
	char str[MAX]; 
	fgets(str,sizeof(str),stdin);

	/* 마지막 문자가 개행(=\n)일 경우, 개행문자 삭제 */
	if(str[strlen(str) - 1] == '\n') 
		str[strlen(str) - 1] = '\0';

	/* 문자 사이 공백 세기 */
	int blank = 0;
	for (int i = 0; i < strlen(str); i++)
		if (str[i] == ' ')
			if (i != 0 && i != strlen(str) - 1)
				blank++;
	
	/* 문장에 공백 1개만 나오는 경우는 예외처리. ex. " " */
	printf("%d", (strlen(str) == 1 && str[0] == ' ') ? blank : blank + 1);

	/* 마무리 */
	return 0;
}

/* 
[stdin으로 입력받을 때 '\n'의 포함 여부?]
fgets 함수를 통해 stdin으로 문자열을 입력받으면, '\n'이 포함된채 문자열이 입력된다.
*/
#pragma warning (disable:4996)
#include <stdio.h>
#include <string.h>

#define MAX 1000002 //'\n'과 '\0'고려.

int main(int argc, char* argv[]) {
	/* 배열 str에 문장 입력 받음. */
	char str[MAX];
	fgets(str, sizeof(str), stdin);

	/* 문자 사이 공백 세기 */
	int blank = 0;
	for (int i = 0; i < strlen(str); i++)
		if (str[i] == ' ')
			if (i != 0 && i != strlen(str) - 2)
				blank++;

	/* 문장에 공백 1개만 나오는 경우는 예외처리. ex. " " */
	printf("%d", (strlen(str) == 2 && str[0] == ' ') ? blank : blank + 1);

	/* 마무리 */
	return 0;
}

/* 
[stdin으로 입력받을 때 '\n'의 포함 여부?]
fgets 함수를 통해 stdin으로 문자열을 입력받으면, '\n'이 포함된채 문자열이 입력된다.
*/
728x90
반응형

'⌨️CS-PS > 백준_문자열' 카테고리의 다른 글

[Baekjoon/백준][1259][C/C++] 팰린드롬수  (0) 2023.02.08