본문 바로가기

C++

[C++] 셋(set)

셋은 키(key)를 저장하며 값은 저장하지 않는다.

셋은 자동으로 데이터를 오름차순으로 정렬하기 때문에 정렬함수는 따로 없고 삽입할 때도 위치를 지정하지 않는다.

그리고 그냥 셋은 중복 키를 허용하지 않으며 멀티셋에서 중복 키를 허용한다.

 

set<Time,TimeComp>와 같이 두번째 인수를 함수 객체로 지정할 수 있다.

그래서 set을 정렬을 위해 비교가 필요할 때 마다 함수 객체의 ()연산자를 호출해서 비교한다.

 

set이 사용하는 디폴트 함수 객체는 less 인데 < 연산자를 사용한다.

셋은 ==연산을 요구하지 않고 < 연산자로 이분 검색을 한다. (함수객체가 less일 경우)

동일한 것은 두 값이 완전히 같은 것, 객체일 경우 모든 멤버까지 같은 것으로, ==연산자를 이용한다.

동등한 것은  두 값이 같은 것으로 인정되는 것이다. 동등한 것은 a와 b가 있을 때 a가 b보다 크지도 않고 a가 b보다

작지도 않을 경우 두 값을 동등하다고 본다.

 

class President
{
public:
     int Id;
     string Name;
     string Addr; 

     President(int aId,char *aName, char *aAddr)
          : Id(aId), Name(aName), Addr(aAddr) { }
          
     void OutPresident() {
          printf("Id:%d, 이름:%s, 주소:%s\n",Id,Name.c_str(),Addr.c_str());
     }
     
     bool operator<(const President &Other) const {
          return Id < Other.Id;
     }
     
     bool operator==(const President &Other) {
          return (Id==Other.Id && Name==Other.Name && Addr==Other.Addr);
     }
}; 

void main()
{
     set<President> King;
     King.insert(President(516,"박정희","동작동"));
     King.insert(President(1212,"전두환","연희동"));
     King.insert(President(629,"노태우","강북"));
     King.insert(President(3030,"김영삼","상도동"));
     King.insert(President(1234,"김대중","강남")); 

     set<President>::iterator it;
     
     for (it=King.begin();it!=King.end();it++) {
          (*it).OutPresident();
     }

     President ZeroThree(3030,"아무개","아무데나");
     it=King.find(ZeroThree);

     if (it != King.end()) {
          cout << "검색되었음" << endl;
          (*it).OutPresident();
     }
     
     it=find(King.begin(),King.end(),ZeroThree);
     
     if (it != King.end()) {
          cout << "검색되었음" << endl;
          (*it).OutPresident();
     }
}

 

President 의 == 연산자는 모든 멤버를 비교하고 (동일성) < 연산자는 id 값만 비교해 우선순위를 매긴다.(동등성)

main에서 Set의 멤버함수인 King.find는 <연산자를 통한 이분 검색만을 하기 때문에 ZeroThree가 검색되었다고 출력한다. 다른 멤버가 달라도 id인 3030인 President가 Set에 들어가 있기 때문이다. 하지만 algorithm의 전역함수 find는

==연산자를 사용하기 때문에 모든 멤버가 같지 않다면 다르기 때문에 검색되었다고 출력하지 않는다.

 

*it = ? 를 통해 임의로 키의 값을 변경하면 안된다. 강제로 임의 값으로 변경하면 정렬 상태가 깨져버린다.

최초        ==> 1 2 3 4 5 6

수정후      ==> 1 2 3 99 5 6

찾는 키가 없습니다.

위와 같이 수정할 경우 검색할 때 5를 찾지 못한다. 왜냐하면 99를 만나 그 다음에 5가 있을 것이라고 생각하지 못하기 때문이다. 그래서 변경하려면 삭제하고 다시 삽입해야 하며 키의 값은 바꿔서는 안된다.

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

[C++] static 멤버와 싱글톤 패턴  (0) 2022.01.17
[C++] 맵(map)  (0) 2022.01.11
[C++] 반복자  (0) 2022.01.10
[C++] 함수 객체  (0) 2022.01.10
[C++] auto_ptr  (0) 2022.01.09