⌨️CS-PS/백준_문자열

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

미르의 블로그 2023. 2. 8. 00:10
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
반응형