DY N DY

실력키우기 단어세기(C++) 본문

PARK/ALGORITHM

실력키우기 단어세기(C++)

손세지 2016. 6. 30. 15:48

1516 : 단어 세기

제한시간: 1000 ms    메모리제한: 32 MB
해결횟수: 857 회    시도횟수: 2302 회   



임의의 문장을 입력받아 각 단어별로 나눈 후에 단어들의 중복되는 개수를 구하는 프로그램을 작성하시오.

 

<처리조건>
(1) 입력된 스트링은 글자의 제한은 없다. 즉 공백이나 ', ' 등도 입력으로 들어 올 수 있다. 
(2) 입력된 문장에서 각 단어사이의 구분은 공백으로 한다. 
(3) 단어에는 공백을 제외한 단어들만이 포함된다.

 

임의의 문장을 입력받는다.(문장의 길이는 200 이하)
하나의 결과가 나온 후에도 계속 새로운 입력을 받다가, "END"가 입력되면 프로그램을 종료하다.



각 단어들의 발생 빈도를 사전순으로 출력한다.


 [Copy]
I AM DOG DOG DOG DOG A AM I 
I AM OLYMPIAD JUNGOL JUNGOL OLYMPIAD
END
 [Copy]
A : 1
AM : 2
DOG : 4
I : 2
AM : 1
I : 1
JUNGOL : 2
OLYMPIAD : 2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**************************************************************
    Problem: 1516
    User: a132034
    Language: C++
    Result: Success
    Time:2 ms
    Memory:1780 kb
****************************************************************/
 
 
#include    <iostream>
#include    <string>
#include    <algorithm>
#include    <sstream>
#include    <vector>
using namespace std;
 
struct op{
    bool operator()(const pair<stringint> left, const pair<stringint> right)
    {
        return left.first < right.first;
    }
};
int main()
{
     
    string str;
 
    while (true)
    {
        vector<pair<stringint>> words;
        getline(cin, str);
 
        if (str == "END")
            break;
 
        stringstream ss(str);
        string buffer;
        while (ss >> buffer)
        {
            bool isMatch = true;
            for (vector<pair<stringint>>::iterator it = words.begin(); it != words.end(); ++it)
            {
                if (it->first == buffer)
                {
                    isMatch = false;
                    it->second++;
                }
            }
            if (isMatch)
                words.push_back(pair<stringint>(buffer, 1));
        }
 
        sort(words.begin(), words.end(), op());
        for (vector<pair<stringint>>::iterator it = words.begin(); it != words.end(); ++it)
        {
            cout << it->first << " : " << it->second << endl;
        }
    }
     
 
    return 0;
}
cs


처음에는 END가 나온 후에 전체 단어를 사전순으로 출력하는줄 알고 결과를 보며 내가 왜 틀렸지?? 하고 한참을 고민하다가...조금 짜증났던 문제. 

둘째로는 한줄을 입력받을 때 마다 새롭게 출력하는 것인줄 알았더니... 이번에는 Output Limit Exceed가 떠서... 도대체 무슨 문제냐.. 하며 코딩시간보다 훨씬 많은 시간 고민했던 문제...


결국 원하는 답은 

한 줄을 입력받을 때 마다 해당 입력받은 줄의 단어를 세서(이전에 입력받은 줄은 초기화) 사전순으로 출력하는 것이었다... 

어쩐지 예제입출력이 이상하게 I가 2번 나오길래... 예제가 잘못됬나? 하고 그냥 무시하고 풀었었는데... 그런 의미였구나.. 


문제 자체는 어려울 것 없다. 단어세기와 거의 동일하나 추가적으로 횟수를 위해 pair<string, int>를 사용했고

사전순으로 출력하기 위해 sort를 사용하였다. 

sort는 시작, 끝 주소값과 (필요시) 어떤 경우에 true를 줄 것인지 정보를 주면 된다.