헤더파일

연관 컨테이너 본문

C++

연관 컨테이너

헤더파일 2018. 4. 30. 15:19

Set - 키 값에 따라 정렬


Map - 키/값 쌍을 키 값에 따라 정렬


Ordered_set/map - 키를 해싱하여 정렬할 곳을 결정


 키는 정렬의 기준으로 삼고자 하는 값이 됩니다. 키는 프로그래머가 어떤 값이든 정할 수 있습니다. 항상 정렬하고 있다는 건 빨리 찾기 위해서 쓰는 겁니다. 


 벡터에도 insert함수가 있어 원하는 위치에 넣을 수 있지만 엄청 안좋은 프로그래밍입니다. 연관컨테이너에서 insert는 알아서 집어넣어줘라는 동작입니다. 연관컨테이너는 내가 위치를 지정할 수 없기 때문에 의미가 있는 것입니다. STL내부에서 알아서 트리의 균형을 잡아주고 정렬하기 때문에 자리를 지정하는 push_back같은 함수는 말도 안됩니다.


Set



set은 키와 벨류가 하나인 컨테이너입니다.


set<int> s{1,3,5,7,9,2,4,6,8,10};


이렇게 초기화하고 출력한다면



set도 begin과 end가 있기 때문에 범위기반 for문을 쓸 수 있습니다.  순서가 바꿔서 출력했다는 건 안에서 두 수를 비교했다는 뜻입니다. 그래서 set에게 다른 조건을 주면 다르게 정렬할 수도 있습니다. Set은 디폴트로 less than 연산자 '<' 로 비교를 하고 Plain Old Data Type은 <연산자가 정의되어 있어 문제가 없습니다.


set<Model> s{ 1,3,5,7,9,2,4,6,8,10 };

사용자정의 클래스를 템플릿으로 Set을 쓰려면 비교함수를 연산자 오버로딩 해줘야 합니다.


bool operator<(const Model& rhs)const

{

return size < rhs.size;

}


중요한 건 인자에 const를 써주고 함수뒤에도 const를 붙여서 맴버변수값을 못 바꾸게 해야 힙니다. emplace는 컨테이너에게 객체를 만드는 권한을 주는 겁니다. 쓸데없는 복사가 일어나지 않아 좋습니다. 


int main()

{

vector<int> v(100000);

iota(v.begin(), v.end(), 1);

set<int> s;

default_random_engine dre;

uniform_int_distribution<> ud(0, 99999);


while (s.size() != 10000)

{

s.insert(ud(dre));

}

auto p = s.begin();

for (int i = 0; i < 10000; ++i)

{

v[*p++] = dre();

}

//벡터는 임의 원소에 접근하는데 상수시간

for (auto& data : v)

{

cout << data << endl;

}

}




벡터에 임의 원소에 접근하는 코드를 set을 이용하면 쉽게 만들 수 있습니다.





vector<string> v(istream_iterator<string>(cin),istream_iterator<string>());


이렇게 쓰는건 v에 그냥 선언문을 넣는 겁니다. 그래서 v는 제대로 선언되지 않습니다. 인자를 중괄호로 묶어 객체로 만든어야 합니다.



multiset<string> v({ istream_iterator<string>(cin),istream_iterator<string>() });


for (auto& data : v)

{

cout << data << endl;

}


멀티 셋을 이용하면 입력받은 문자열을 순식간에 정렬할 수 있습니다.





ifstream in("Lecture.cpp");

multiset<string> v({ istream_iterator<string>(in),istream_iterator<string>() });


for (auto& data : v)

{

cout << data << "\t";

}


콘솔에서 단어를 읽었다면 파일에서도 똑같이 할 수 있습니다. 문장은 같은 요소가 나올 가능성이 높기 때문에 multiSet으로 중복을 허용합니다.


MAP


map은 키 값과 value가 따로 있는 자료형입니다.


map<string, int>m;

m.insert(pair<string, int>("루피", 500000000));

m.insert(make_pair("푸딩", 1234567));


map에 데이터를 넣을 때는 pair를 이용해서 값을 넣는데 자료형을 써서 pair를 만들거나 알아서 만들라고 make_pair 함수를 써서 insert 해줍니다.


m["나미"] = 200000000;


이런식으로 적으면 먼저 키값을 찾아 있으면 그값을 바꾸고 없으면 Insert 하는 행동을 합니다.


for (const auto& data : m)

{

cout << data.first << " : " << data.second << endl;

}


map의 데이터는 pair로 구성되어 있으므로 first, second로 요소에 접근합니다.



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

반복자  (0) 2018.05.21
Map을 이용한 파일입출력  (0) 2018.05.14
노말분포 & 시퀀스 컨테이너  (0) 2018.04.16
컨테이너 - 3  (0) 2018.04.12
컨테이너 - 2  (0) 2018.04.09
Comments