Set
집합을 관리하기 위한 자료구조이다.
- 구현하려면 C++ 에서는 BST(Balanced binary search tree(red-balck tree) 로 구현한다.
- c++ set library 이용하면 기본적인 searching 과 update 를 모두 O(log n) 시간에 수행 가능하다.
- c++ 에서는 set 의 element 간에 순서가 정해지지 않은 경우 사용할 수 있는 unordered_set library 또한 지원한다.이는 hash table 로 구현되어 있으며 따라서 모든 연산을 AVERAGE O(1) 에 구현 가능하다. => 경시대회에서는 거의 쓰지않음
#include <set>
#include <iostream>
using namespace std;
int main() {
set<int> s;
s.insert(3);
s.insert(2);
s.insert(5);
cout << s.count(3) << endl;
cout << s.count(4) << endl;
s.erase(3);
s.insert(4);
cout << s.count(3) << endl;
cout << s.count(4) << endl;
}
cout << s.size() << endl;
for (auto x : s) // SET 원소 순회
{
cout << x << endl;
}
auto it = s.find(7); // 원하는 원소를 찾는 과정
if (it == s.end())
{
cout << "7 is not found" << endl;
}
Set 에서 가장 큰 element와 작은 element 찾기
auto first = s.begin();
auto last = s.end(); last--; // end()함수는 마지막이 아닌 마지막 다음 위치를 나타내는 프린터이므로 --해준다.
특정 element 이상 첫번째 element 출력
cout << *s.lower_bound(x) << endl; //x 이상인데 가장 작은 첫번째 element 출력
cout << *s.upper_bound(x) << endl;
Map
<key, value> pair 을 관리하기 위한 data structure 이다
- Set 과 마찬가지로 C++ 에서는 balanced binary search tree(red-black tree) 로 map library 를 구현한다.
즉 기본적인 searching과 update 를 모두 O(log n) 시간에 수행 가능하다.
- Map 에서 각 Key 는 반드시 Unique 해야 하며 C++ 에서는 중복된 key 값을 허용하는 multimap library 를 따로 지원한다.
- Unordered_set 과 마찬가지로 C++ 에서는 Hash table 로 구현된 unordered_map library 또한 지원한다. ( 경시대회는 적합x)
map<string, int> m;
m["monkey"] = 4;
m["banana"] = 3;
m["harpsichord"] = 9;
cout << m["banana"] << endl;
//없는 키값 접근시 <해당키, 0> 을 map 에 추가한다.
cout << m["akdljf"] << endl;
if (m.count("banana"))
{
//key exists
// 0 이면 존재 x, 1이면 존재
} for (auto x : m)
{
cout << x.first << " " << x.second << endl;
//x.first = key / x.second = value
}
ex) Uva 11572 Unique Snowflakes
주어진 sequence 에서 unique element 만으로 이루어진 가장 긴 substring의 길이를 출력하는 문제
linear search 로 해결할 경우 O(n^2) 시간이 걸림
linear search 를 한번만 수행하면서 같은 원소 k를 만난 경우 1. 현재 저장된 최대 개수 혹은 2. 이전에 마지막으로 k가 저장된 다음 위치로부터 count 한 snowflake 의 개수들 중 하나만 답이 된다. (Why)
다만 모든 종류의 snowflake 에 대해 마지막 위치를 저장할 경우 경우의 수가 10^9이므로 메모리 제한을 넘어갈 것으로 보인다.
Priority Queue
Insert : element 추가
Findmin : Priority 가 가장 높은 element 반환
Deletemin: Priority 가 가장 높은 element 제거
- 보통 findmin 과 그 외 operation 들 간의 balance 를 고려하여 모든 연산을 O(log n) 에 지원하는 binary heap 으로 구현
- 'Priority 가 높다' 에는 여러가지 기준이 있으며 priority 가 integer일 때 기준으로 C++ 는 가장 큰 숫자가 (max-heap based), Java 의 경우 가장 작은 숫자(min-heap based) 가 priority 가 가장 높음 ( C++은 내림차순)
- 같은 연산을 기준으로 할 때 priority queue 는 map 보다 훨 씬 빠르다.
-size(), empty() 등의 함수 제공
-priority queue 를 min-heap based 로 바꾸고 싶을 경우(오름차순)
1. priority 가 number 인 경우에 한해 각 priority 에 -1을 곱해서 insert 하거나
(꺼낸 다음에 다시 -1 곱해야함을 주의할 것)
2. 아래와 같이 greater를 사용
priority_queue<int, vector<int> , greater<int>> q;
- Priority queue 뿐만 아니라 C++ 의 partial_sort 또한 binary heap 으로 구현되어 있다.
priority_queue<int> q;
q.push(3);
q.push(5);
q.push(7);
q.push(2);
cout << q.top() << endl;
q.pop();
cout << q.top() << endl;
q.pop();
q.push(6);
cout << q.top() << endl;
q.pop();
ex) Uva 1203 Argus
가장 먼저 출력되는 K의 task (Q_num) 을 순서대로 출력하는 것
Priority queue 를 사용하여 가장 period 가 작은 task i를 delete 한 뒤 해당 Q_num 을 출력하고 Q_num + 다음 시간을 다시 priority queue 에 insert 해준다.
예제코드 O(Nlog K)
Union find data Structure
Union find 는 disjoint set들을 관리하기 위하 data structure 로서 , 다음과 같이 3개의 operation 을 지원한다.
1. makeset(x) : 단일 element x로 이루어진 set을 하나 생성한다.
2. find(x) : x가 포함된 set을 return 한다.
3. union (x,y) : x가 포함된 set과 y과 포함된 set을 하나의 set으로 합친다.
- 위 연산을 C++ set의 vector 로 구현할 수도 있지만 비효율적이다
- Union-find 는 각 set을 rooted tree로 관리하고, 각 tree의 root 를 대표 element 로 지정한다. 각 대표 element 는 rank 를 가지고 있다.
- Rank 는 path compression 을 가정하지 않을 시 해당 tree 의 height 로 정의한다.
- union 시 merged tree의 rank 가 작아지는 쪽으로 union 을 수행한다.
'알고리즘' 카테고리의 다른 글
[알고리즘 #4] Problem Solving Paradigms (1) (0) | 2023.04.19 |
---|---|
[알고리즘 #1] Introduction (0) | 2023.04.18 |
[알고리즘 #7] Graph Algorithm (2) (0) | 2023.04.13 |
[알고리즘 #2] Sorting, Searching, Data Structures (0) | 2023.04.10 |
[알고리즘 #6] 그래프 이론 (0) | 2023.04.06 |