복습이 필요한 알고 팁

Set을 잘 써보자. (map 에 관한것도 조금)

헐랭미 2020. 6. 12. 15:46

set의 특징 : 

- 원소의 중복을 허용하지 않는다.

- 원소는 오름차순으로 정렬이 되어있다. 

- vector, map 처럼 []를 허용하지 않는다.

 

 

첫번째와 두번째를 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#define pii pair<intint>
using namespace std;
 
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    set<int> s = { 7,1,2,3,5,1,5,2,3,1 };
 
    set<int>::iterator itr = s.begin();
 
    for (itr; itr != s.end(); itr++)
        cout << *itr;
    // 1. 어떻게 나오나???
 
    s.erase(4);
    // 2. 어떻게 나오나? 그리고 s.erase(4) 의 의미는?
    
}
cs

 

Q : 이 코드의 결과값은???

A : {1,2,3,5,7} 이다.

 

문제

Q :  s.erase() 는 무언가를 지운다는 느낌의 함수이다. 

      그러면 저 함수에서 s.erase(4); 를 하면 결과가 어떻게 될까?

A :  1 2 3 5 7

     굉장히 5번째 수를 지운다는 느낌이 강했지만 답은 "4"라는 데이터를 삭제하는 것이다!!!!!!!

 

 

- vector, map 처럼 []를 허용하지 않는다. 를보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <set>
#include <vector>
#include <map>
#define pii pair<intint>
using namespace std;
 
int main()
{
    vector<int> v = { 1,2,3,4 };
    map<intint> m = { {1,10}, {2,20}, {3,30}, {4,40} };
    set<int> s = { 1,2,3,4 };
 
    cout << v[1<< ' ';
    cout << m[1<< ' ';
    cout << s[1<< ' ';
}
cs

 

Q : 이것의 출력값은 각각 어떻게 되나?

A : 2, 10, ERROR  이다. v[1] 은 첫번째 위치, m[1] 은 key값 1의 value값 이다.

    set은 그런거 없다.

 

 

 

 

 

* Set의 주의점 좀 더 응용과정

ex) set<Point> s 를 만들것인데 Point는 (x,y) 로 이뤄져있고 s의 순서는 x좌표는 내림차순으로 먼저, 그다음 y좌표를 오름차순으로 하고 싶다. (이거 비슷한 문제가 백준에 있었는데 까먹었다)

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
#include <iostream>
#include <set>
#include <vector>
#include <map>
#define pii pair<intint>
using namespace std;
 
class point
{
public :
    int x, y;
 
    
};
 
class comp
{
public :
    bool operator() (const point& p1, const point& p2) const
    {
        return p1.x > p2.x;
    }
 
};
 
int main()
{
 
    set<point, comp> s = { {1,3},{2,3},{2,1}, {4,1}, {5,5} };
 
    set<point>::iterator itr = s.begin();
 
    while (itr != s.end())
    {
        cout << (*itr).x << ' ' << (*itr).y << '\n';
        itr++;
    }
}
cs

Q : 이것의 결과값을 써봐라.

A : 5 5

    4 1

    2 3 

    1 3 이다. 엥??????????? 2,1은 어디갔어???????????

   ->set의 특성상 특별한 조건이 없을 때 수가 같으면 중복으로 인지하고 삭제를 한다.

      즉 x가 같을때의 조건을 안걸어서 그렇다. 

 

 

 

21,22번째 줄을 보면 해당 과정을 수정하였다.

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
#include <iostream>
#include <set>
#include <vector>
#include <map>
#define pii pair<intint>
using namespace std;
 
class point
{
public :
    int x, y;
 
    
};
 
class comp
{
public :
    bool operator() (const point& p1, const point& p2) const
    {
        if (p1.x == p2.x)
            return p1.y < p2.y;
        else
            return p1.x > p2.x;
    }
 
};
 
int main()
{
 
    set<point, comp> s = { {1,3},{2,3},{2,1}, {4,1}, {5,5} };
 
    set<point>::iterator itr = s.begin();
 
    while (itr != s.end())
    {
        cout << (*itr).x << ' ' << (*itr).y << '\n';
        itr++;
    }
}
cs