헤더파일
Map을 이용한 파일입출력 본문
텍스트파일은 UTF-8형식으로 BOM(Byte order Marker)이 있는 파일입니다. 그래서 출력해보면 앞에 이상한 문자가 나옵니다. 그래서 3바이트를 건너뛰어야 합니다.
int main()
{
string fname = "이상한 나라의 앨리스.txt";
ifstream in(fname);
char c;
if (!in)
{
cout << "test"<<endl;
return 0;
}
in >> c >> c >> c;
map<char, int> cimap;
while (in >> c)
{
cimap.operator[](c)++;
}
for (const auto& d : cimap)
cout << d.first << " : " << d.second << endl;
return 0;
}
pair<char, int>& d 이렇게 쓰면 pair의 char와 int의 자료형이 망가질 수 있기 때문에 컴파일러 오류가 납니다. const pair<char, int>& d 이렇게 써야합니다. auto& d는 오류가 안 나는데 map에서 넘겨줄때 자동으로 const형태로 넘겨주기 때문입니다. 그래도 명시적으로 const를 쓰는게 좋습니다.
int main()
{
string fname = "이상한 나라의 앨리스.txt";
ifstream in(fname);
char c;
if (!in)
{
cout << "failed"<<endl;
return 0;
}
in >> c >> c >> c;
map<char, int> cimap;
while (in >> c)
{
cimap.operator[](c)++;
}
//출현 횟수가 키가 되는 맵을 만든다.
map<int, char> icmap;
for (const auto& d : cimap)
{
icmap.insert(make_pair(d.second, d.first));
}
for (const auto& d : icmap)
cout << d.first << " : " << d.second << endl;
return 0;
}
몇 가지 수정사항이 있습니다.
map<int, char,greater<int>> icmap;
3번째 인자로 함수객체를 넣어서 정렬순서를 다르게 할 수 있습니다.
결과값에서도 중복값을 날려버리기 때문에 모든 알파벳이 다 계산되지 않습니다. multimap을 써야 합니다.
복사를 한번 줄이기 위해 icmap.emplace(d.second, d.first); 를 씁니다.
int main()
{
string fname = "이상한 나라의 앨리스.txt";
ifstream in(fname);
char c;
if (!in)
{
cout << "failed"<<endl;
return 0;
}
in >> c >> c >> c;
string word;
map<string, int> cimap;
while (in >> word)
{
cimap.operator[](word)++;
}
//출현 횟수가 키가 되는 맵을 만든다.
multimap<int, string ,greater<int>> icmap;
for (const auto& d : cimap)
{
icmap.emplace(d.second, d.first);
}
auto p = icmap.cbegin();
for (int i = 0; i < 30; ++i)
{
cout << "[" << p->second << "]" << " : " << p->first << endl;
++p;
}
return 0;
}
단어 단위로 하는 것도 간단합니다.
map은 빨리 찾기위한 컨테이너 입니다. 굳이 find함수를 쓸 필요없습니다. log시간에 찾을 수 있고 map만의 find함수가 있습니다. map은 삽입시간을 포기해서 검색시간을 얻습니다.
while (true)
{
cout << "찾는 단어는? ";
string temp;
cin >> temp;
auto p = cimap.find(temp);
if (p!=cimap.end())
{
cout << cimap[temp] << "번 사용되었습니다." << endl;
}
else
cout << "찾으시는 단어가 없습니다." << endl;
}
for루프를 사용해서 문제를 해결하였다면 다른 방법을 생각해 보자. 같은 기능이 알고리즘에 있을 것입니다.
int max = 0;
string result;
auto p = max_element(cimap.begin(), cimap.end(), [](const auto& a,const auto& b) {
return a.first.length() < b.first.length();
});
cout << p->first << endl;
제일 큰 수를 찾는 max_element 함수를 이용해서 제일 긴 단어를 찾을 수 있습니다.