Bakjoon Q1152 - C++

Q1152


Problem

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

Input

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

Output

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

예제 입력

1
 The first character is a blank

예제 출력

1
6

나의 제출

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <bits/stdc++.h>
using namespace std;

int main(){
    int ans=0, x=0;
    char n;
    while(~scanf("%c", &n)){ //EOF를 입력받을 때까지
        if(n==' '){
            if(x==0)
                ; //first filtering
            else
                ans++;
        }
        x=1;
    }
    if(n == '\0'){printf("0"); return 0;} //zero word filtering
    if(n==' ')
        ans--; //last filtering / last memorized n equals to whitespace
    printf("%d", ans+1);
}

참고 제출

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
 
int main()
{
    //cin.tie(NULL);
	//ios::sync_with_stdio(false); 이 두 문장을 쓰면 연산 속도가 44ms 에서 8ms 까지 줄어든다.
    string input;
    int textCount = 0;
    while (cin >> input)
    // cin은 whitespace를 무시하기 때문에 '단어'를 입력받을 때 +1 하고 space가 나온 다음 다시 단어를 입력받는다.
    {
        textCount++;
    }
    cout << textCount;
}

추가 내용

내가 쓴 풀이는 진짜로 대체 내가 왜 틀렸는지 도저히 이해가 안간다. 좀 더 맑은 정신일때 다시 분석해보려고 한다.

이와 별개로, 참고 제출한 풀이는 정말 경이로운 풀이이다. cin이 whitespcae를 무시한다는 특성을 이용해서, cin » input을 while 조건문에 넣으므로서 입력을 word1 word2 word3 이런식으로 쪼개서 받는 셈이다. 따라서 word가 입력되었을 경우에만 cnt +1 가 되는 것이다. 진짜 미친 풀이.

총평

내용 자체는 아주 단순한 문제이다. 공백이 연속으로 올 수 없기 때문에, general한 cass에서는 보통 단어 수 = 공백 + 1일 것이다. 따라서 우리가 고려해 주어야 할 것은 문장 맨 앞과 뒤에 공백이 오는 경우뿐이다. 이를 filtering할 수만 있으면 아주 쉽게 풀 수 있다. 다른 이들의 solution을 보았을 때는 무려 10^6 size의 char array를 define 해주고 loop로 입력 받는 순간의 모든 array 원소를 검사하는 방식을 취했다. (근데 생각보다 memory를 많이 안먹는 것 같기도 하다…?)

보기엔 쉬웠는데 내 풀이가 왜 틀렸는지 이해가 안가는 문제…