헤더파일

Map을 이용한 파일입출력 본문

C++

Map을 이용한 파일입출력

헤더파일 2018. 5. 14. 15:22

텍스트파일은 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 함수를 이용해서 제일 긴 단어를 찾을 수 있습니다.

'C++' 카테고리의 다른 글

알고리즘 함수  (0) 2018.05.31
반복자  (0) 2018.05.21
연관 컨테이너  (0) 2018.04.30
노말분포 & 시퀀스 컨테이너  (0) 2018.04.16
컨테이너 - 3  (0) 2018.04.12
Comments