CS โ find vs binary search
๐ 05/05 โ std::find vs std::binary_search (์ ํ ํ์ vs ์ด๋ถ ํ์)
๋ชจ์๋ฉด์ ์ฃผ์ : โstd::find()์ std::binary_search()์ ์ฐจ์ด์ ์ ๋ํด์ ์ค๋ช ํด ์ฃผ์ธ์โ ์ ๋ ฌ ์ ์ โ ์๊ฐ๋ณต์ก๋ โ ๋ฐํ ํ์ ์ฐจ์ด โ lower_boundยทequal_range โ set/map ๋ฉค๋ฒ ํจ์ vs ์๊ณ ๋ฆฌ์ฆ ๊ผฌ๋ฆฌ์ง๋ฌธ ์ฐ๊ฒฐ ๋ค๋ฆฌ
ํ์ต ์์ญ ์ ํ์ โ ์ปจํ ์ด๋์์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก
13~16๋ฒ์์ STL ์ปจํ
์ด๋ ์ ๋ฐ(์ํ์คยท์ฐ๊ดยท๋น์์ยท์ด๋ํฐ)์ ์ ๋ฆฌํ๋ค๋ฉด, 17๋ฒ๋ถํฐ๋ ๊ทธ ์์์ ๋์ํ๋ <algorithm> ํค๋์ ํ์ ํจ์๋ฅผ ๋ค๋ฃน๋๋ค.
1
2
3
4
13~16๋ฒ STL ์ปจํ
์ด๋ โ ์๋ฃ๊ตฌ์กฐ (์ด๋์ ๋ด์๊น)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
17๋ฒ std::find vs std::binary_search โ
โ ์๊ณ ๋ฆฌ์ฆ (์ด๋ป๊ฒ ์ฐพ์๊น)
์ดํ sort / lower_bound / equal_range โ ์ ๋ ฌยท๋ฒ์ ์๊ณ ๋ฆฌ์ฆ family
์ด ์ฃผ์ ๋ ๋ฉด์ ์์ โ๋ ํจ์์ ์ฐจ์ด๋?โ ์์ผ๋ก ์ข๊ฒ ๋ค์ด์๋ ๊ฒฐ๊ตญ (1) ์ ๋ ฌ ์ ์ โ (2) ์๊ฐ๋ณต์ก๋ โ (3) ๋ฐํ ํ์ ์ฐจ์ด โ (4) ๋ ๋์ ๋์(lower_bound) โ (5) set/map ๋ฉค๋ฒ ํจ์์์ ๋น๊ต๋ก ํผ์ณ์ง๋๋ค. ๋จ์ํ โ์ ํ vs ์ด๋ถโ์ด๋ผ๊ณ ๋ง ๋ตํ๋ฉด ๊ผฌ๋ฆฌ์ง๋ฌธ์์ ๋งํ๋๋ค.
๋ชจ์๋ฉด์ ๋ต๋ณ
std::find์ std::binary_search๋ ๋ ๋ค <algorithm> ํค๋์ ํ์ ํจ์์ง๋ง ์ ์ ์กฐ๊ฑด๊ณผ ์๊ฐ๋ณต์ก๋, ๋ฐํ ํ์
์ด ๋ชจ๋ ๋ค๋ฆ
๋๋ค.
std::find๋ ์ ํ ํ์์
๋๋ค. [first, last) ๊ตฌ๊ฐ์ ์ฒ์๋ถํฐ ๋๊น์ง ์ํํ๋ฉด์ == ์ฐ์ฐ์๋ก ๊ฐ์ ๋น๊ตํ๊ณ , ์ผ์นํ๋ ์ฒซ ์์์ iterator๋ฅผ ๋ฐํํฉ๋๋ค. ๋ชป ์ฐพ์ผ๋ฉด last๋ฅผ ๋ฐํํฉ๋๋ค. ์๊ฐ๋ณต์ก๋๋ O(n)์ด๊ณ ์ปจํ
์ด๋๊ฐ ์ ๋ ฌ๋ผ ์์ ํ์๊ฐ ์์ผ๋ฉฐ, vectorยทlistยทdeque ๋ฑ ์ด๋ค ์ํ์ค์๋ ์ธ ์ ์์ต๋๋ค.
std::binary_search๋ ์ด์ง ํ์์
๋๋ค. O(log n)์ผ๋ก ๋น ๋ฅธ ๋์ ์ฌ์ ์ ๋ ฌ์ด ํ์ ์ ์ ์
๋๋ค. ๋ ๋น๊ต ๋ฐฉ์์ด ==์ด ์๋๋ผ < ์ฐ์ฐ์ ๋ ๋ฒ์ผ๋ก ๋์น๋ฅผ ํ๋จํฉ๋๋ค โ !(a < b) && !(b < a)์ด๋ฉด ๊ฐ๋ค๊ณ ๋ด
๋๋ค. ๊ฒฐ์ ์ ์ธ ์ฐจ์ด๋ ๋ฐํ ํ์
์ด bool ํ๋๋ฟ์ด๋ผ๋ ์ ์
๋๋ค. โ์๋/์๋โ๋ง ์๋ ค์ฃผ๊ณ ์์น๋ ์ ์๋ ค์ค๋๋ค. ๊ทธ๋์ ์์น๊น์ง ํ์ํ๋ฉด ๋ณดํต std::lower_bound๋ std::equal_range๋ฅผ ์๋๋ค. ์ฌ์ค binary_search ๋ด๋ถ ๊ตฌํ ์์ฒด๊ฐ lower_bound ํธ์ถ์ด๊ณ , ์ ๋ ฌ๋์ง ์์ ์ปจํ
์ด๋์ ์ฌ์ฉํ๋ฉด ๊ฒฐ๊ณผ๋ ๋ฏธ์ ์ ๋์(UB)์
๋๋ค.
์ ํ ๊ธฐ์ค์ ๋จ์ํฉ๋๋ค. ์ ๋ ฌ๋ผ ์๊ณ ์์น๊ฐ ํ์ ์์ผ๋ฉด binary_search, ์์น iterator๊ฐ ํ์ํ๋ฉด lower_bound, ์ ๋ ฌ๋ผ ์์ง ์๊ฑฐ๋ ์ผํ์ฑ์ด๋ฉด find. ๊ทธ๋ฆฌ๊ณ ์๋ฃ๊ตฌ์กฐ ์์ฒด๊ฐ ํธ๋ฆฌ/ํด์์ธ std::setยทstd::mapยทstd::unordered_map์์๋ ์๊ณ ๋ฆฌ์ฆ ํจ์ ๋์ ๋ฉค๋ฒ ํจ์ find()๋ฅผ ์จ์ผ ํฉ๋๋ค โ ์๊ณ ๋ฆฌ์ฆ ํจ์๋ ์ปจํ
์ด๋ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๋ฌด์ํ๊ณ O(n)์ผ๋ก ๋๋ ๋ฐ๋ฉด, ๋ฉค๋ฒ ํจ์๋ ํธ๋ฆฌ๋ O(log n), ํด์๋ ํ๊ท O(1)์ ๋ณด์ฅํ๊ธฐ ๋๋ฌธ์
๋๋ค.
ํต์ฌ ๊ฐ๋
| ๋ถ๋ฅ | ํค์๋ | ํ ์ค ์ ์ |
|---|---|---|
| ์ ์ | std::find | ์ ํ ํ์. [first, last) ์ํ, ==๋ก ๋น๊ต, iterator ๋ฐํ |
| ย | std::binary_search | ์ด๋ถ ํ์. ์ ๋ ฌ ํ์, <๋ก ๋น๊ต, bool ๋ฐํ |
| ํค๋ | <algorithm> | ๋ ํจ์ ๋ชจ๋ ๊ฐ์ ํค๋์ ์ ์ |
| ์๊ฐ๋ณต์ก๋ | O(n) ์ ํ | find โ ์ต์
n๋ฒ ๋น๊ต |
| ย | O(log n) ์ด๋ถ | binary_search โ ์ต์
logโ(n)+1 ๋ฒ ๋น๊ต |
| ๋ฐํ ํ์ | iterator | find โ ์์น ์ ๋ณด (๋ชป ์ฐพ์ผ๋ฉด last) |
| ย | bool | binary_search โ ์กด์ฌ ์ฌ๋ถ๋ง |
| ๋น๊ต ์ฐ์ฐ์ | == | find โ equality ๋น๊ต |
| ย | < ๋ ๋ฒ | binary_search โ !(a<b) && !(b<a) ๋์น ํ๋จ |
| ์ ์ | ์ ๋ ฌ ๋ถํ์ | find |
| ย | ์ฌ์ ์ ๋ ฌ ํ์ | binary_search โ ์ ๋๋ฉด UB |
| ย | Random Access ๊ถ์ฅ | binary_search๋ list์ ์จ๋ ๋์์ ํ์ง๋ง O(n) ๊ฑฐ๋ฆฌ ๊ณ์ฐ์ด ๋ค์ด๊ฐ |
| ๊ด๋ จ ํจ์ | std::lower_bound | ์ ๋ ฌ ๊ตฌ๊ฐ์์ value ์ด์ ์ฒซ ์์น iterator ๋ฐํ. binary_search ๋ด๋ถ ๊ตฌํ |
| ย | std::upper_bound | ์ ๋ ฌ ๊ตฌ๊ฐ์์ value ์ด๊ณผ ์ฒซ ์์น iterator ๋ฐํ |
| ย | std::equal_range | {lower_bound, upper_bound} ์ ๋ฐํ. ๋์ผ ํค ๋ฒ์ |
| ๋ฉค๋ฒ vs ์๊ณ ๋ฆฌ์ฆ | set/map::find | RB-Tree O(log n) ๋ฉค๋ฒ ํจ์ โ ๋ฐ๋์ ์ด๊ฑธ ์ |
| ย | unordered_map::find | ํด์ ํ๊ท O(1) ๋ฉค๋ฒ ํจ์ |
| ย | ์๊ณ ๋ฆฌ์ฆ std::find | ์ปจํ
์ด๋ ๊ตฌ์กฐ ๋ฌด์ O(n) โ ์ฐ๊ด ์ปจํ
์ด๋์ ์ฐ๋ฉด ์ํด |
| ํจ์ | ์ ๋ ฌ ์ ๋ ์ปจํ ์ด๋ + binary_search | ๋ฏธ์ ์ ๋์ (UB) |
| ย | strict weak ordering ๊นจ์ง | ๋น๊ต์๊ฐ ์๋ชป๋๋ฉด binary_search ๊ฒฐ๊ณผ ๋ณด์ฅ ์ ๋จ |
| ์ธ๋ฆฌ์ผ | Algo::Find | std::find ๋์ (์ ํ) |
| ย | Algo::BinarySearch | std::binary_search ๋์. int32 ์ธ๋ฑ์ค ๋ฐํ (INDEX_NONE = -1) |
| ย | TArray::Find | ๋ฉค๋ฒ ํจ์. ์ธ๋ฑ์ค ๋ฐํ |
๋ชฉ์ฐจ
- ํต์ฌ ์์ฝ ์นด๋
- std::find โ ์ ํ ํ์
- std::binary_search โ ์ด๋ถ ํ์
- ํต์ฌ ์ฐจ์ด์ 5๊ฐ์ง
- ๊ด๋ จ ์๊ณ ๋ฆฌ์ฆ family โ lower_bound / upper_bound / equal_range
- ์ฝ๋ ๋น๊ต โ vector ๊ธฐ๋ฐ
- ๊ผฌ๋ฆฌ์ง๋ฌธ ์์ ๊ฒฝ๋ก
- ์ธ๋ฆฌ์ผ์์์ ํ์ โ Algo::Find / Algo::BinarySearch
- ๋ณด๊ฐ โ iterator ยท ๋์นํ๋จ ยท lower_bound vs find
- ๋ณด๊ฐ โ ํฐ ๋ฐ์ดํฐ์์ find vs binary_search ์ ํ
1. ํต์ฌ ์์ฝ ์นด๋
30์ด ๋ต๋ณ
1
2
3
4
5
std::find = ์ ํ ํ์, O(n), iterator ๋ฐํ, ์ ๋ ฌ ๋ถํ์, == ๋น๊ต
std::binary_search = ์ด๋ถ ํ์, O(log n), bool ๋ฐํ, ์ ๋ ฌ ํ์, < ๋น๊ต
์์น๊น์ง ํ์ํ๋ฉด โ std::lower_bound (binary_search ๋ด๋ถ ๊ตฌํ)
set/map/unordered_map โ ๋ฉค๋ฒ ํจ์ find() ์ฌ์ฉ (์๊ณ ๋ฆฌ์ฆ X)
๊ผฌ๋ฆฌ์ง๋ฌธ ์ฐ๊ฒฐ ๋งต
1
2
3
4
5
6
7
8
9
std::find vs binary_search
โโโ ์ binary_search๋ bool๋ง? โ lower_bound๊ฐ ์์น ๋ด๋น, ๋ถ์
์ค๊ณ
โโโ ์ ๋ ฌ ์ ๋๋๋ฐ binary_search? โ UB (Undefined Behavior)
โโโ lower_bound vs upper_bound vs equal_range โ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ family
โโโ set/map์์๋? โ ๋ฉค๋ฒ ํจ์ find() (O(log n) / O(1) ๋ณด์ฅ)
โ โโโ ์ ์๊ณ ๋ฆฌ์ฆ std::find๋ ์ํด? โ ์ปจํ
์ด๋ ๋ด๋ถ ๊ตฌ์กฐ ๋ฌด์ โ O(n)
โโโ < ๋ ๋ฒ์ผ๋ก ๋์น? โ strict weak ordering, == ์ฐ์ฐ์ ์์ด๋ ๋จ
โโโ list์ binary_search? โ ๋์์ ํจ. ๋จ ๊ฑฐ๋ฆฌ ๊ณ์ฐ O(n) โ ์๋ฏธ ์์
โโโ Random Access Iterator vs Forward Iterator
2. std::find โ ์ ํ ํ์
ํต์ฌ ํ ๋ฌธ์ฅ
std::find๋[first, last)๊ตฌ๊ฐ์ ์ฒ์๋ถํฐ ์ํํ๋ฉฐ==์ฐ์ฐ์๋ก ๊ฐ์ ๋น๊ตํด, ์ผ์นํ๋ ์ฒซ ์์์ iterator๋ฅผ ๋ฐํํ๋ ์ ํ ํ์์ ๋๋ค.
์๊ทธ๋์ฒ
1
2
3
4
#include <algorithm>
template <class InputIt, class T>
InputIt find(InputIt first, InputIt last, const T& value);
- ํค๋:
<algorithm> - ๋ฐํ:
value์ ์ผ์นํ๋ ์ฒซ iterator. ๋ชป ์ฐพ์ผ๋ฉดlast - ์๊ฐ๋ณต์ก๋: ์ต์
O(n), ์ต์O(1)(์ฒซ ์์๊ฐ ์ผ์น) - ์๊ตฌ iterator:
InputIterator(๊ฐ์ฅ ์ฝํ ์๊ตฌ์ฌํญ โforward_list,istream_iterator๋ฑ๋ ๊ฐ๋ฅ) - ๋น๊ต ๋ฐฉ์:
*it == value(equality)
์ฌ์ฉ ์์
1
2
3
4
5
6
7
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
auto it = std::find(v.begin(), v.end(), 5);
if (it != v.end()) {
std::cout << "์ฐพ์! ์ธ๋ฑ์ค: " << std::distance(v.begin(), it) << "\n";
} else {
std::cout << "์์\n";
}
๋ณํ
std::find_ifโ ์ ์ด(predicate) ๊ธฐ๋ฐ.==๋์ ๋๋ค๋ก ์กฐ๊ฑด ์ง์ std::find_if_notโ ์กฐ๊ฑด์ ๋ง์กฑํ์ง ์๋ ์ฒซ ์์
1
auto it = std::find_if(v.begin(), v.end(), [](int x){ return x > 4; });
3. std::binary_search โ ์ด๋ถ ํ์
ํต์ฌ ํ ๋ฌธ์ฅ
std::binary_search๋ ์ ๋ ฌ๋ ๊ตฌ๊ฐ์์<์ฐ์ฐ์ ๋ ๋ฒ์ผ๋ก ๋์น๋ฅผ ํ๋จํ๋ฉฐ ์ด๋ถ ํ์์ผ๋ก ๊ฐ์ ์กด์ฌ ์ฌ๋ถ๋ง ํ์ธํด,bool๋ง ๋ฐํํฉ๋๋ค.
์๊ทธ๋์ฒ
1
2
3
4
5
6
7
8
#include <algorithm>
template <class ForwardIt, class T>
bool binary_search(ForwardIt first, ForwardIt last, const T& value);
// ๋น๊ต์ ๋ฒ์
template <class ForwardIt, class T, class Compare>
bool binary_search(ForwardIt first, ForwardIt last, const T& value, Compare comp);
- ํค๋:
<algorithm> - ๋ฐํ:
boolโ ์์ผ๋ฉดtrue, ์์ผ๋ฉดfalse. ์์น๋ ๋ชจ๋ฆ - ์๊ฐ๋ณต์ก๋:
O(log n)๋น๊ต ํ์. ๋จRandomAccessIterator๊ฐ ์๋๋ฉด ๊ฑฐ๋ฆฌ ๊ณ์ฐ์ดO(n)์ด ๋ค์ด๊ฐ - ์๊ตฌ iterator:
ForwardIterator์ด์ (์คํจ๋RandomAccessIterator) - ๋น๊ต ๋ฐฉ์:
!(a < b) && !(b < a)โ<๋ ๋ฒ์ผ๋ก ๋์น ํ๋จ
์ฌ์ฉ ์์
1
2
3
4
5
6
7
8
9
std::vector<int> v = {1, 1, 2, 3, 4, 5, 6, 9}; // โ
๋ฐ๋์ ์ ๋ ฌ
bool found = std::binary_search(v.begin(), v.end(), 5);
std::cout << (found ? "์์" : "์์") << "\n"; // ์์
// ์์น๊น์ง ์๊ณ ์ถ๋ค๋ฉด โ lower_bound
auto it = std::lower_bound(v.begin(), v.end(), 5);
if (it != v.end() && *it == 5) {
std::cout << "์์น: " << std::distance(v.begin(), it) << "\n";
}
ํจ์
- ์ ๋ ฌ ์ ๋ ์ปจํ ์ด๋: ๊ฒฐ๊ณผ ๋ณด์ฅ X โ Undefined Behavior
==์ฐ์ฐ์๋ง ์ ์๋ ํ์ : ์ปดํ์ผ์ ๋์ง๋ง ์๋ฏธ๊ฐ ๊นจ์ง.<๋น๊ต์๊ฐ strict weak ordering์ ๋ง์กฑํด์ผ ํจstd::list์ ์ฌ์ฉ: ๋์์ ํ์ง๋ง ๊ฑฐ๋ฆฌ ๊ณ์ฐ์ดO(n)โ ์๋ฏธ ์์
4. ํต์ฌ ์ฐจ์ด์ 5๊ฐ์ง
| ํญ๋ชฉ | std::find | std::binary_search |
|---|---|---|
| ์๊ณ ๋ฆฌ์ฆ | ์ ํ ํ์ | ์ด๋ถ ํ์ |
| ์๊ฐ๋ณต์ก๋ | O(n) | O(log n) (๋น๊ต ํ์ ๊ธฐ์ค) |
| ์ฌ์ ์ ๋ ฌ | ๋ถํ์ | ํ์ (์ ๋๋ฉด UB) |
| ๋ฐํ ํ์ | Iterator (์์น) | bool (์กด์ฌ ์ฌ๋ถ๋ง) |
| ๋น๊ต ์ฐ์ฐ์ | == (equality) | < ๋ ๋ฒ (strict weak ordering) |
| ์๊ตฌ iterator | InputIterator | ForwardIterator (์คํจ๋ RandomAccess) |
| ์ ์ฉ ์ปจํ ์ด๋ | vector, list, deque, forward_list, ๋ชจ๋ ์ํ์ค | ์ ๋ ฌ๋ vector, deque, array (RandomAccess ๊ถ์ฅ) |
| ์ฌ์ฉ ์์ | ์ ๋ ฌ ์ ๋จ / ์ผํ์ฑ / ์์น ํ์ | ์ ๋ ฌ ์๋ฃ / ๋คํ ์กฐํ / ์กด์ฌ๋ง ํ์ธ |
| ํจ์ | n ํฌ๋ฉด ๋๋ฆผ | ์ ๋ ฌ ์ ๋๋ฉด UB |
์ ์ด๋ฐ ์ฐจ์ด๊ฐ ์๊ฒผ๋
find๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ํ์ โ ์ด๋ค iterator๋ ๋ฐ๊ณ ์ด๋ค ์ปจํ ์ด๋๋ ๋ฐ๊ธฐ ์ํด ์ ํ์ผ๋ก ์ค๊ณ๋จ. ์์น ์ ๋ณด๊ฐ ํต์ฌ์ด๋ผ iterator ๋ฐํ.binary_search๋ ์ ๋ ฌ ์๋ฃ์ ํนํ๋ ๋น ๋ฅธ ์กฐํ โ ์์น ์ฑ ์์ ๋ถ๋ฆฌํด์lower_bound๊ฐ ๊ฐ์ ธ๊ฐ. ๊ทธ๋์binary_search๋ ๋จ์ํbool๋ง ๋ฐํ.- ์ด๊ฒ STL์ ๋ถ์
์ค๊ณ ์ฒ ํ: ์กด์ฌ ํ์ธ์
binary_search, ์์น ํ์ธ์lower_bound, ๋ฒ์ ํ์ธ์equal_range.
5. ๊ด๋ จ ์๊ณ ๋ฆฌ์ฆ family โ lower_bound / upper_bound / equal_range
ํต์ฌ ํ ๋ฌธ์ฅ
binary_search๋ด๋ถ๋lower_boundํธ์ถ์ด๊ณ , ์์นยท๋ฒ์๊ฐ ํ์ํ๋ฉดlower_boundยทupper_boundยทequal_range์ ์ด ์ ๋ ฌ ์๋ฃ ํ์์ ์ง์ง ๋๊ตฌ์ ๋๋ค.
์๊ทธ๋์ฒ
1
2
3
4
5
6
7
8
9
10
11
template <class ForwardIt, class T>
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value);
// value ์ด์์ธ ์ฒซ ์์น
template <class ForwardIt, class T>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value);
// value ์ด๊ณผ์ธ ์ฒซ ์์น
template <class ForwardIt, class T>
std::pair<ForwardIt, ForwardIt> equal_range(ForwardIt first, ForwardIt last, const T& value);
// {lower_bound, upper_bound} ์ โ value์ ๊ฐ์ ์์๋ค์ ๋ฒ์
binary_search ๋ด๋ถ ๊ตฌํ (๊ฐ๋ )
1
2
3
4
5
template <class It, class T>
bool binary_search(It first, It last, const T& value) {
auto it = std::lower_bound(first, last, value);
return it != last && !(value < *it); // <๋ง ์ฌ์ฉ (==์ ์ ์)
}
โ binary_search๋ lower_bound + ๋์น ๊ฒ์ฌ ํ ์ค์ง๋ฆฌ wrapper์
๋๋ค. โ ์ด๊ฑธ ์๋ฉด โ์ binary_search๋ iterator ์ ๋๋ ค์ค?โ์ ๋ต์ด ๋ช
ํํด์ง๋๋ค โ lower_bound๊ฐ ์ด๋ฏธ ๊ทธ ์ญํ .
๋น๊ต ํ
| ํจ์ | ๋ฐํ | ์ฉ๋ | ๋น๊ณ |
|---|---|---|---|
binary_search | bool | ์กด์ฌ ์ฌ๋ถ๋ง | ๋ด๋ถ๋ lower_bound |
lower_bound | iterator | value ์ด์ ์ฒซ ์์น | ์ฝ์ ์์น ๊ฒฐ์ ์๋ ์ฌ์ฉ |
upper_bound | iterator | value ์ด๊ณผ ์ฒซ ์์น | lower_bound์ ์ |
equal_range | pair<It, It> | ๊ฐ์ ๊ฐ๋ค์ ๋ฒ์ | multiset/multimap์์ ์์ฃผ |
์ ๋ ฌ ์ปจํ ์ด๋์์ multi ํค ๋ค๋ฃฐ ๋
1
2
3
std::vector<int> v = {1, 2, 2, 2, 3, 4}; // ์ ๋ ฌ + ์ค๋ณต
auto [lo, hi] = std::equal_range(v.begin(), v.end(), 2);
std::cout << "2์ ๊ฐ์: " << std::distance(lo, hi) << "\n"; // 3
6. ์ฝ๋ ๋น๊ต โ vector ๊ธฐ๋ฐ
find ์ฌ์ฉ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6}; // ์ ๋ ฌ X
// ์ ํ ํ์ โ ์ด๋ค ์์๋ OK
auto it = std::find(v.begin(), v.end(), 5);
if (it != v.end()) {
std::cout << "find: ์์น " << std::distance(v.begin(), it)
<< ", ๊ฐ " << *it << "\n";
}
// ์ถ๋ ฅ: find: ์์น 4, ๊ฐ 5
}
binary_search ์ฌ์ฉ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
std::sort(v.begin(), v.end()); // โ
์ฌ์ ์ ๋ ฌ ํ์
// v = {1, 1, 2, 3, 4, 5, 6, 9}
bool found = std::binary_search(v.begin(), v.end(), 5);
std::cout << "binary_search: " << (found ? "์์" : "์์") << "\n";
// ์ถ๋ ฅ: binary_search: ์์
// ์์น๊น์ง ํ์ํ๋ฉด lower_bound
auto it = std::lower_bound(v.begin(), v.end(), 5);
if (it != v.end() && *it == 5) {
std::cout << "lower_bound: ์์น " << std::distance(v.begin(), it) << "\n";
}
// ์ถ๋ ฅ: lower_bound: ์์น 5
}
์ฑ๋ฅ ์ฐจ์ด ์ฒด๊ฐ (n = 1,000,000)
1
2
์ ๋ ฌ ์ ํจ + std::find โ ํ๊ท ~500,000 ๋น๊ต (O(n))
์ ๋ ฌ 1ํ (O(n log n)) + std::binary_search 100๋ง ๋ฒ โ ์ฝ 20 ๋น๊ต ร 100๋ง
โ ๋คํ ์กฐํ๋ฉด ์ ๋ ฌ + binary_search๊ฐ ์๋์ , ์ผํ์ฑ์ด๋ฉด find๊ฐ ๋จ์ํ๊ณ ๋น ๋ฆ.
7. ๊ผฌ๋ฆฌ์ง๋ฌธ ์์ ๊ฒฝ๋ก
Q1. โ์ binary_search๋ iterator๋ฅผ ์ ๋๋ ค์ฃผ๋์?โ
STL์ ์ฑ ์์ ๋ถ๋ฆฌํด์ ์ค๊ณํ์ต๋๋ค. ์กด์ฌ ์ฌ๋ถ๋ง ํ์ธํ๋ ๋น ๋ฅธ ๊ฒฝ๋ก๋
binary_search(bool), ์์น๊น์ง ์๊ณ ์ถ์ผ๋ฉดlower_bound(iterator), ๊ฐ์ ๊ฐ๋ค์ ๋ฒ์๋equal_range(pair). ์ฌ์คbinary_search๋ด๋ถ ๊ตฌํ ์์ฒด๊ฐlower_bound๋ฅผ ํธ์ถํ ๋ค!(value < *it)ํ ์ค๋ก ๋์น ๊ฒ์ฌ๋ง ํ๋ wrapper์ ๋๋ค. ์์น๊ฐ ํ์ํ๋ฉดlower_bound๋ฅผ ์ง์ ๋ถ๋ฅด๋ ๊ฒ ๋ ํจ์จ์ ์ด์์.
Q2. โ์ ๋ ฌ ์ ๋ ์ปจํ ์ด๋์ binary_search ์ฐ๋ฉด ์ด๋ป๊ฒ ๋๋์?โ
Undefined Behavior์ ๋๋ค. ํ์ค์ โ์ ๋ ฌ๋ผ ์๋คโ๋ฅผ ์ ์ ๋ก๋ง ๋์์ ๋ณด์ฅํฉ๋๋ค. ์ด์ด ์ข์ผ๋ฉด ์ฐ์ฐํ ๋ง์ ์๋ ์์ง๋ง ์ผ๋ฐ์ ์ผ๋ก๋ ์๋ชป๋ ๊ฒฐ๊ณผ ๋๋ ๋ฌดํ ๋ถํ ๋ก ๋๋์ง ์์ ์๋ ์์ต๋๋ค. ๊ทธ๋์
binary_searchํธ์ถ ์ ์ ๋ฐ๋์std::is_sorted๋ก ๊ฒ์ฆํ๊ฑฐ๋std::sort๋ก ์ ๋ ฌํด์ผ ํฉ๋๋ค.
Q3. โset์ด๋ map์์๋ ๋ฉค๋ฒ ํจ์ find์ ์๊ณ ๋ฆฌ์ฆ std::find ์ค ๋ญ ์จ์ผ ํ๋์?โ
๋ฐ๋์ ๋ฉค๋ฒ ํจ์
find()์ ๋๋ค.std::set::find๋ RB-Tree๋ฅผ ํ๊ณO(log n),std::unordered_map::find๋ ํด์ ๋ฒํท ํ ๋ฒ ์กฐํ๋ก ํ๊ทO(1)์ ๋ณด์ฅํฉ๋๋ค. ๋ฐ๋ฉด ์๊ณ ๋ฆฌ์ฆstd::find๋ ์ปจํ ์ด๋ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๋ชจ๋ฅด๊ณ ๊ทธ๋ฅ iterator๋ฅผ ์ฒ์๋ถํฐ ๋๊น์ง ๋๋O(n)์ ํ ํ์์ ๋๋ค. ์๋ฃ๊ตฌ์กฐ์ ์ฅ์ ์ ํต์งธ๋ก ๋ฒ๋ฆฌ๋ ์ ์ด๋ผ ์ ๋ ์ ์๋๋ค. ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋ฉค๋ฒ ํจ์๊ฐ ๋ฐ๋ก ์๋ค๋ฉด ๊ฑฐ์ ํญ์ ๊ทธ๊ฒ ๋ ๋น ๋ฆ ๋๋ค.
Q4. โbinary_search์ ๋น๊ต๊ฐ < ๋ ๋ฒ์ธ ์ด์ ๋?โ
strict weak ordering ๋ง ์๊ตฌํ๋ STL์ ์ผ๊ด๋ ์ค๊ณ ๋๋ฌธ์ ๋๋ค.
==์ฐ์ฐ์๊ฐ ์ ์๋์ง ์์ ํ์ (์: ์ฌ์ฉ์ ์ ์ ํด๋์ค)๋<๋ง ์ ์๋ผ ์์ผ๋ฉดbinary_search๋ฅผ ์ธ ์ ์์ต๋๋ค.!(a < b) && !(b < a)๊ฐ ์ฐธ์ด๋ฉด ๋ ๊ฐ์ โ๋๋ฑโํ๋ค๊ณ ๊ฐ์ฃผํฉ๋๋ค. ์ด๊ฑดstd::set์ด๋std::map์ด<๋น๊ต์๋ง์ผ๋ก ๋์ํ๋ ๊ฒ๊ณผ ๊ฐ์ ์๋ฆฌ์ ๋๋ค.
Q5. โlist์ binary_search ์ฐ๋ฉด ๋์ํ๋์?โ
๋์์ ํฉ๋๋ค.
binary_search๋ForwardIterator๋ง ์๊ตฌํ๋๊น์. ํ์ง๋งstd::list๋RandomAccessIterator๊ฐ ์๋๋ผ ์ค๊ฐ ์์น๋ก ์ ํํ๋ ๋ฐO(n)๊ฑฐ๋ฆฌ ๊ณ์ฐ์ด ๋ค์ด๊ฐ๋๋ค. ๊ฒฐ๊ตญ ๋น๊ต ํ์๋งO(log n)์ด์ง ์ ์ฒด๋O(n)์ด ๋ผ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ์ด๋ถ ํ์์ ์ด๋์ ๋ณด๋ ค๋ฉดvector,deque,array์ฒ๋ผ random access๊ฐ ๊ฐ๋ฅํ ์ปจํ ์ด๋๋ฅผ ์จ์ผ ํฉ๋๋ค.
Q6. โfind์ binary_search ์ธ์ ๋ค๋ฅธ ํ์ ์๊ณ ๋ฆฌ์ฆ์?โ
std::find_if(์ ์ด ๊ธฐ๋ฐ ์ ํ),std::find_first_of(์ฌ๋ฌ ํ๋ณด ์ค ์ฒซ ์ผ์น),std::adjacent_find(์ธ์ ๋์ผ ์์),std::search(๋ถ๋ถ ์ํ์ค ๋งค์นญ),std::count/std::count_if(๊ฐ์ ์ธ๊ธฐ),std::any_of/std::all_of/std::none_of(์กฐ๊ฑด ์ถฉ์กฑ ์ฌ๋ถ) ๋ฑ์ด ์์ต๋๋ค. ์ ๋ ฌ ์๋ฃ ์ ์ฉ์ผ๋ก๋ ์์ ๋งํlower_boundยทupper_boundยทequal_range๊ฐ ํต์ฌ family์ ๋๋ค.
Q7. โbinary_search ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์ ์์น๋ฅผ ๋ lower_bound๋ก ์ฐพ์ผ๋ฉด ๋นํจ์จ ์๋๊ฐ์?โ
์ ํํฉ๋๋ค. ๊ทธ๋์ ์์น๊ฐ ํ์ํ๋ฉด ์ฒ์๋ถํฐ
lower_bound๋ง ๋ถ๋ฅด๋ ๊ฒ ์ ์์ ๋๋ค. ํจํด์ ์ด๋ ๊ฒ ๋ฉ๋๋ค:
1 2 3 4 auto it = std::lower_bound(v.begin(), v.end(), value); if (it != v.end() && *it == value) { // ์ฐพ์ + ์์น๋ it }
binary_search๋ ์ ๋ง โ์๋ ์๋โ๋ง ํ์ํ ๋, ๋๋ ์๋๋ฅผ ๋ช ํํ ํํํ๊ณ ์ถ์ ๋๋ง ์๋๋ค.
8. ์ธ๋ฆฌ์ผ์์์ ํ์ โ Algo::Find / Algo::BinarySearch
ํต์ฌ ํ ๋ฌธ์ฅ
์ธ๋ฆฌ์ผ์
Algo::๋ค์์คํ์ด์ค์std::์๊ณ ๋ฆฌ์ฆ ๋์ ํจ์๋ฅผ ๋๊ณ , ์ปจํ ์ด๋ ์์ฒด์๋Find๊ฐ์ ๋ฉค๋ฒ ํจ์๋ฅผ ์ ๊ณตํด ์ธ๋ฑ์ค ๋๋ ํฌ์ธํฐ ๊ธฐ๋ฐ์ผ๋ก ๋์ํฉ๋๋ค.
๋์ ํ
| std:: | Unreal Algo:: / ๋ฉค๋ฒ ํจ์ | ๋ฐํ |
|---|---|---|
std::find | Algo::Find(Arr, Value) | T* (๋ชป ์ฐพ์ผ๋ฉด nullptr) |
std::find_if | Algo::FindByPredicate | T* |
std::binary_search | Algo::BinarySearch(Arr, Value) | int32 ์ธ๋ฑ์ค (๋ชป ์ฐพ์ผ๋ฉด INDEX_NONE = -1) |
std::lower_bound | Algo::LowerBound | int32 |
std::upper_bound | Algo::UpperBound | int32 |
std::sort | Algo::Sort | void |
TArray::Find | (๋ฉค๋ฒ ํจ์) | int32 ์ธ๋ฑ์ค |
TArray::Contains | (๋ฉค๋ฒ ํจ์) | bool |
์ฝ๋ ์์
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "Algo/Find.h"
#include "Algo/BinarySearch.h"
TArray<int32> Arr = {3, 1, 4, 1, 5, 9, 2, 6};
// ์ ํ ํ์ โ ์ธ๋ฑ์ค
int32 Idx = Arr.Find(5); // TArray ๋ฉค๋ฒ ํจ์
if (Idx != INDEX_NONE) { /* ... */ }
// ์ ํ ํ์ โ ํฌ์ธํฐ
int32* Ptr = Algo::Find(Arr, 5);
if (Ptr) { /* *Ptr ์ฌ์ฉ ๊ฐ๋ฅ */ }
// ์ด๋ถ ํ์ (์ ๋ ฌ ํ์)
Arr.Sort(); // 1, 1, 2, 3, 4, 5, 6, 9
int32 BIdx = Algo::BinarySearch(Arr, 5);
if (BIdx != INDEX_NONE) { /* ... */ }
์ฐจ์ด์
- ์ธ๋ฆฌ์ผ์
int32์ธ๋ฑ์ค ๋ฐํ์ ์ ํธ โINDEX_NONE(-1) ๋งคํฌ๋ก๋ก not-found ํํ Algo::Find๋ ํฌ์ธํฐ ๋ฐํ โnullptr๊ฒ์ฌ๋ก not-found ์ฒ๋ฆฌTArray::Find/TArray::Containsโ ๋ฉค๋ฒ ํจ์๊ฐ ๊ฐ์ฅ ์ผ๋ฐ์ . ์๊ณ ๋ฆฌ์ฆ ํจ์๋ณด๋ค ์ฝ๋๊ฐ ๊ฐ๊ฒฐ- ์ธ๋ฆฌ์ผ์
<algorithm>์ง์ ์ฌ์ฉ๋ ๊ฐ๋ฅํ์ง๋งAlgo::family์ ๋ฉค๋ฒ ํจ์๊ฐ ์ปจ๋ฒค์
9. ๋ณด๊ฐ โ iterator ยท ๋์นํ๋จ ยท lower_bound vs find
๋ณธ๋ฌธ์ ์ฝ๊ณ ์ถ๊ฐ๋ก ์๊ธด ์๋ฌธ(2026-05-06)์ ํ ์น์ ์ผ๋ก ๋ฌถ์. โ iterator๊ฐ ๋ญ๊ฐ โก find๋ ์ธ๋ฑ์ค๋ฅผ ๋๋ ค์ฃผ๋๊ฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋๋ ค์ฃผ๋๊ฐ โข ๋์นํ๋จ์ด๋ โฃ lower_bound์ find์ ๊ฒฐ์ ์ ์ฐจ์ด.
9-1. iterator๋
์ปจํ ์ด๋ ์์๋ฅผ ๊ฐ๋ฆฌํค๋ โํฌ์ธํฐ ๊ฐ์ ๊ฐ์ฒดโ. ํฌ์ธํฐ์ฒ๋ผ ์ญ์ฐธ์กฐยท์ฆ๊ฐยท๋น๊ต๊ฐ ๊ฐ๋ฅํ์ง๋ง,
vectorยทlistยทmap๋ฑ ๋ด๋ถ ๊ตฌ์กฐ๊ฐ ๋ค๋ฅธ ์ปจํ ์ด๋๋ฅผ ๊ฐ์ ์ธํฐํ์ด์ค๋ก ๋ค๋ฃจ๊ธฐ ์ํ ์ถ์ํ์ ๋๋ค.
ํต์ฌ ์ฐ์ฐ ์ธ ๊ฐ์ง:
| ์ฐ์ฐ | ์๋ฏธ |
|---|---|
*it | ์ญ์ฐธ์กฐ โ ๊ฐ๋ฆฌํค๋ ์์์ ๊ฐ |
++it | ๋ค์ ์์๋ก ์ด๋ |
it == end | ๋์ธ์ง ๋น๊ต (==/!=) |
1
2
3
4
5
6
std::vector<int> v = {3, 1, 4};
auto it = v.begin(); // ์ฒซ ์์๋ฅผ ๊ฐ๋ฆฌํด
*it; // 3
++it; // ๋ ๋ฒ์งธ๋ก ์ด๋
*it; // 1
v.end(); // โ
๋ง์ง๋ง์ "๋ค์" ์๋ฆฌ โ ์ ํจ ์์ X (past-the-end)
end()๋ ์ ํจ ์์๊ฐ ์๋๋ค โ ๋ง์ง๋ง ์์ ๋ค์์ ๊ฐ์ ์์น(past-the-end). ๊ทธ๋์ STL์ ๋ชจ๋ ์๊ณ ๋ฆฌ์ฆ์ [first, last) ๋ฐ์ด๋ฆฐ ๊ตฌ๊ฐ์ผ๋ก ๋์ํฉ๋๋ค. find๊ฐ ๋ชป ์ฐพ์ผ๋ฉด last๋ฅผ ๋ฐํํ๋ค๋ ๋ง์ โ์ ํจํ์ง ์์ ๋ ์๋ฆฌโ๋ฅผ ๊ฐ๋ฆฌํจ๋ค๋ ๋ป์ด๋ผ ์์ ํฉ๋๋ค.
iterator ์นดํ ๊ณ ๋ฆฌ (๊ฐํจ ์)
| ์นดํ ๊ณ ๋ฆฌ | ๊ฐ๋ฅ ์ฐ์ฐ | ๋ํ ์ปจํ ์ด๋ |
|---|---|---|
| Input | ++it, *it(์ฝ๊ธฐ ์ ์ฉ, 1ํ) | istream_iterator |
| Forward | + *it๋ก ์ฌ๋ฌ ๋ฒ ์ฝ๊ธฐ | forward_list |
| Bidirectional | + --it ์ญ๋ฐฉํฅ | list, set, map |
| Random Access | + it + n, it[n], it < it2 | vector, deque, array |
โ binary_search๊ฐ vector์์ ์ง์ง O(log n)์ธ ์ด์ = Random Access์ฌ์ ์ค๊ฐ ์ ํ๊ฐ O(1). โ list์ binary_search๋ฅผ ์จ๋ ๋์ํ์ง๋ง ์ ํ๊ฐ O(n)์ด๋ผ ์๋ฏธ ์๋ ์ด์ ๋ ๊ฐ์.
9-2. find๋ ์ธ๋ฑ์ค? iterator?
std::find๋ iterator๋ฅผ ๋ฐํํฉ๋๋ค. ์ธ๋ฑ์ค ์๋๋๋ค. ๋ชป ์ฐพ์ผ๋ฉด ์ธ๋ฑ์ค -1์ด ์๋๋ผlast(=v.end()) ๋ฅผ ๋๋ ค์ค๋๋ค.
1
2
3
4
5
6
auto it = std::find(v.begin(), v.end(), 999);
if (it == v.end()) { /* ๋ชป ์ฐพ์ */ } // โ ์ ์ ํจํด
if (it != v.end()) { /* ์ฐพ์ โ *it ์ฌ์ฉ ๊ฐ๋ฅ */ }
// ์ธ๋ฑ์ค๊ฐ ํ์ํ๋ฉด ๋ณํ
int idx = std::distance(v.begin(), it);
์ธ์ดยท๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ณ not-found ํํ ์ฐจ์ด โ ํท๊ฐ๋ฆฌ๋ ์ง์
| API | ๋ฐํ ํ์ | ๋ชป ์ฐพ์์ ๋ |
|---|---|---|
std::find (C++ STL) | iterator | last (= end()) |
std::string::find | size_t | std::string::npos (= -1์ unsigned๋ก) |
TArray::Find (Unreal) | int32 ์ธ๋ฑ์ค | INDEX_NONE (= -1) |
Algo::Find (Unreal) | T* ํฌ์ธํฐ | nullptr |
std::map::find (๋ฉค๋ฒ) | iterator | end() |
โ โfind๋ ๋ชป ์ฐพ์ผ๋ฉด -1โ ์ std::string์ด๋ ์ธ๋ฆฌ์ผ ์ปจ๋ฒค์
์ด์ง, <algorithm>์ std::find๊ฐ ์๋. โ ๋ชจ๋ STL ์๊ณ ๋ฆฌ์ฆ์ not-found = last ๋ก ํต์ผ.
9-3. ๋์นํ๋จ(equivalence) โ ==์ด ์๋๋ผ < ๋ ๋ฒ
binary_search๋==๋ก ๊ฐ์์ง ๋ณด์ง ์๊ณ<๋ฅผ ๋ ๋ฒ ํธ์ถํด โ์ด๋ ์ชฝ๋ ๋ ์์ง ์๋คโ ๋ก ๊ฐ์์ง ํ๋จํฉ๋๋ค. ์ด๊ฑธ ๋์น(equivalence) ๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ, ์ผ๋ฐ ๋๋ฑ์ฑ(equality)๊ณผ ๊ตฌ๋ถ๋ฉ๋๋ค.
1
2
3
4
5
// equality (find์ ๋ฐฉ์)
a == b
// equivalence (binary_search ยท set ยท map์ ๋ฐฉ์)
!(a < b) && !(b < a)
์ ๊ตณ์ด ์ด๋ ๊ฒ?
<๋ง ์ ์๋ผ ์์ด๋ ๋์ํ๋๋ก ๋ง๋ STL์ ์ผ๊ด๋ ์ค๊ณ- ์ฌ์ฉ์ ์ ์ ํด๋์ค์์
==์ ์ ๋ง๋ค๊ณ<๋ง ๋ง๋ค์ด๋binary_searchยทsetยทmap์ด ๋ชจ๋ ์๋ - ์ด๊ฑธ strict weak ordering์ด๋ผ๊ณ ๋ถ๋ฆ โ
<๋น๊ต์๊ฐ ๋ง์กฑํด์ผ ํ๋ ์ํ์ ์กฐ๊ฑด
1
2
3
4
5
6
7
8
9
10
struct Point {
int x, y;
bool operator<(const Point& o) const { return x < o.x; }
// operator== ์์ด๋ OK
};
std::vector<Point> pts = { {1,0}, {3,0}, {5,0} };
std::binary_search(pts.begin(), pts.end(), Point{3, 99});
// โ x์ขํ๋ง ๋น๊ต โ !(3<3) && !(3<3) = true โ ๋์น๋ก ํ๋จ โ true
// y๊ฐ ๋ฌ๋ผ๋ "๋์น"๋ก ๋ด โ ์ด๊ฒ equivalence์ equality์ ํต์ฌ ์ฐจ์ด
โ ==๋ ๊ฐ์ฒด ์์ฒด๊ฐ ๊ฐ์ (entity equality) โ ๋์น๋ ์์ ๊ธฐ์ค์์ ๊ฐ์ ์์น (์ด๋ ์ชฝ๋ ๋ ์์ง ์์) โ ๋์ด ๋ค๋ฅผ ์ ์๋ค๋ ์ ์ด ํจ์ โ set์์ ๊ฐ์ ํค๋ก ์ทจ๊ธ๋๋ ๋ ๊ฐ์ด ==๋ก๋ ๋ค๋ฅผ ์ ์์.
9-4. lower_bound vs find โ ๊ฒฐ์ ์ ์ฐจ์ด
๋ ๋ค โ์์น iterator๋ฅผ ๋๋ ค์ค๋คโ๋ ์ ์ ๊ฐ์ง๋ง, ์ ์ ยท์๊ฐ๋ณต์ก๋ยท๋ฐํ ์๋ฏธยท๋ถ๊ฐ ๋ฅ๋ ฅ์ด ๋ค๋ฆ ๋๋ค. ๊ฐ์ฅ ํฐ ํจ์ ์ lower_bound๋ ๋ชป ์ฐพ์๋
last๊ฐ ์๋ ์์น๋ฅผ ๊ฐ๋ฆฌํฌ ์ ์๋ค๋ ์ .
๋น๊ตํ
| ํญ๋ชฉ | std::find | std::lower_bound |
|---|---|---|
| ์๊ณ ๋ฆฌ์ฆ | ์ ํ | ์ด๋ถ |
| ์ ๋ ฌ ์ ์ | ๋ถํ์ | ํ์ |
| ์๊ฐ๋ณต์ก๋ | O(n) | O(log n) |
| ๋น๊ต ์ฐ์ฐ์ | == | < |
| ๋ฐํ | ์ผ์นํ๋ ์ฒซ iterator | value ์ด์์ธ ์ฒซ iterator |
| ๋ชป ์ฐพ์ ๋ ๋ฐํ | last (๋ช
ํ) | last ๋๋ value๋ณด๋ค ํฐ ๋ค๋ฅธ ์์น (์ถ๊ฐ ๊ฒ์ฌ ํ์) |
| ๋ถ๊ฐ ์ฉ๋ | ์์น ์ฐพ๊ธฐ๋ง | ์ ๋ ฌ ์ ์ง ์ฝ์ ์์น ๊ณ์ฐ |
| iterator ์๊ตฌ | InputIterator | ForwardIterator (์คํจ RandomAccess) |
ํจ์ โ lower_bound๋ ๋ ๋จ๊ณ ๊ฒ์ฌ๊ฐ ํ์
1
2
3
4
5
6
7
8
9
10
std::vector<int> v = {1, 3, 5, 7}; // ์ ๋ ฌ๋จ, 4๋ ์์
// (A) find โ ํ ๋ฒ๋ง ๊ฒ์ฌํ๋ฉด ๋จ
auto it1 = std::find(v.begin(), v.end(), 4);
if (it1 != v.end()) { /* ์ฐพ์ */ } // it1 == end() ๋ผ์ ์ง์
์ ํจ โ ๋ช
ํ
// (B) lower_bound โ it๋ 5๋ฅผ ๊ฐ๋ฆฌํด (4 ์ด์ ์ฒซ ์์น)
auto it2 = std::lower_bound(v.begin(), v.end(), 4);
// it2 != v.end() ๋ง ๊ฒ์ฌํ๋ฉด ์ ๋จ!
if (it2 != v.end() && *it2 == 4) { /* ์ฐพ์ */ } // โ ๋ ๋จ๊ณ ๊ฒ์ฌ ํ์
โ find์ last๋ โ์๋คโ โ lower_bound์ last๋ โvalue๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ๊ฒ ํ๋๋ ์๋คโ (์ฆ ๋ชจ๋ ์์๊ฐ value ๋ฏธ๋ง) โ lower_bound๊ฐ last๊ฐ ์๋ ์์น๋ฅผ ๊ฐ๋ฆฌ์ผ๋ ๊ทธ๊ฒ value์ธ์ง ์๋์ง๋ ๋ณ๋ ๊ฒ์ฌ ํ์.
lower_bound๋ง์ ๋ฅ๋ ฅ โ ์ ๋ ฌ ์ ์ง ์ฝ์
1
2
3
4
std::vector<int> v = {1, 3, 5, 7};
auto pos = std::lower_bound(v.begin(), v.end(), 4);
v.insert(pos, 4);
// v = {1, 3, 4, 5, 7} โ ์ ๋ ฌ ์ ์ง
โ find๋ก๋ ๋ถ๊ฐ๋ฅ. lower_bound๋ โํ์ + ์ฝ์
์์น ๊ฒฐ์ โ ๋ ์ญํ ์ ๊ฒธํฉ๋๋ค. โ ๊ทธ๋์ ์ ๋ ฌ๋ ์๋ฃ์์ โ์ด ๊ฐ์ด ์๋์ง + ์์ผ๋ฉด ์ด๋ ๋ผ์ธ์งโ๋ฅผ ํ ๋ฒ์ ์ฒ๋ฆฌํ ๋ lower_bound๋ง ๋ถ๋ฅด๋ฉด ๋จ.
9-5. equal_range โ ์ฌ์ฉ๋ฒ๊ณผ ๋ฐํ๊ฐ ๋ถํด
std::equal_range๋ ์ ๋ ฌ ๊ตฌ๊ฐ์์value์ ๋์น์ธ ์์๋ค์ ๋ฒ์๋ฅผpair<iterator, iterator>๋ก ๋ฐํํฉ๋๋ค. ์ฆ{lower_bound, upper_bound}ํ ์์ ํ ๋ฒ์ ๋๋ ค์ค๋๋ค. ์ค๋ณต์ด ์๋ ์ ๋ ฌ ์๋ฃ์์ โ๊ฐ์ ๊ฐ์ด ์ด๋๋ถํฐ ์ด๋๊น์ง๋โ๋ฅผ ๊ตฌํ ๋ ํต์ฌ.
์๊ทธ๋์ฒ
1
2
3
4
5
6
7
8
template <class ForwardIt, class T>
std::pair<ForwardIt, ForwardIt>
equal_range(ForwardIt first, ForwardIt last, const T& value);
// ๋น๊ต์ ๋ฒ์
template <class ForwardIt, class T, class Compare>
std::pair<ForwardIt, ForwardIt>
equal_range(ForwardIt first, ForwardIt last, const T& value, Compare comp);
- ํค๋:
<algorithm> - ๋ฐํ:
pair<It, It>โ.first= lower_bound,.second= upper_bound - ์๊ฐ๋ณต์ก๋:
O(log n)๋น๊ต (RandomAccess ๊ธฐ์ค) - ์ ์ : ์ ๋ ฌ๋ผ ์์ด์ผ ํจ (์ ๋๋ฉด UB)
๋ฐํ๊ฐ์ ์๋ฏธ ์๊ฐํ
1
2
3
4
5
6
7
8
9
v = {1, 2, 2, 2, 3, 4} (์ธ๋ฑ์ค 0 1 2 3 4 5)
^
equal_range(v.begin(), v.end(), 2)
โโโโโ .first (lower_bound) โ ์ธ๋ฑ์ค 1, *it == 2 (์ฒซ 2)
โ โโโ .second (upper_bound) โ ์ธ๋ฑ์ค 4, *it == 3 (2 ๋ค์ ์ฒซ ์์น)
โผ โผ
[1] [2] [2] [2] [3] [4]
โโโโ ๋์น ๋ฒ์ [first, second) = ์ธ๋ฑ์ค 1~3 โโโโ
โ .first = value ์ด์ ์ฒซ ์์น (= ์ฒซ ๋ฑ์ฅ ์์น) โ .second = value ์ด๊ณผ ์ฒซ ์์น (= ๋ง์ง๋ง ๋ฑ์ฅ + 1, ๋ฐ์ด๋ฆฐ ๋) โ [.first, .second) ๋ฐ์ด๋ฆฐ ๊ตฌ๊ฐ์ด value์ ๋์น์ธ ์์ ์ ์ฒด
์ฌ์ฉ ํจํด โ 4๊ฐ์ง
โ ๊ฐ์ ์ธ๊ธฐ
1
2
3
std::vector<int> v = {1, 2, 2, 2, 3, 4};
auto [lo, hi] = std::equal_range(v.begin(), v.end(), 2); // C++17 ๊ตฌ์กฐ์ ๋ฐ์ธ๋ฉ
std::cout << std::distance(lo, hi) << "\n"; // 3
โก ์กด์ฌ ์ฌ๋ถ ํ์ธ
1
2
3
auto [lo, hi] = std::equal_range(v.begin(), v.end(), 2);
if (lo != hi) { /* ์์ */ } // ๊ฑฐ๋ฆฌ > 0
else { /* ์์ */ } // ๊ฑฐ๋ฆฌ == 0 โ ๋ iterator๊ฐ ๊ฐ์ ์์น
โ ๋ชป ์ฐพ์์ ๋๋ .first == .second ๊ฐ ๋๋ฉฐ ๊ฐ์ ์์น๋ฅผ ๊ฐ๋ฆฌํด โ ๊ทธ ์๋ฆฌ๊ฐ ์ฝ์
์์น.
โข ๋์น ์์ ์ ์ฒด ์ํ
1
2
3
4
auto [lo, hi] = std::equal_range(v.begin(), v.end(), 2);
for (auto it = lo; it != hi; ++it) {
std::cout << *it << " "; // 2 2 2
}
โฃ ๊ตฌ์กฐ์ ๋ฐ์ธ๋ฉ ์์ด (C++14 ์ดํ)
1
2
3
4
auto p = std::equal_range(v.begin(), v.end(), 2);
auto lo = p.first;
auto hi = p.second;
int cnt = static_cast<int>(std::distance(lo, hi));
multiset / multimap์์์ ํ์ฉ
equal_range๊ฐ ์ง์ง ๋น์ ๋ณด๋ ๊ณณ์ ์ค๋ณต ํค๋ฅผ ํ์ฉํ๋ ์ฐ๊ด ์ปจํ ์ด๋์ ๋๋ค. ๊ฐ์ ํค์ ๋ชจ๋ ๊ฐ์ ํ ๋ฒ์ ์ก์๋ผ ๋.
1
2
3
4
5
6
7
8
9
std::multimap<std::string, int> scores = {
{"Alice", 90}, {"Alice", 85}, {"Bob", 70}, {"Alice", 95}
};
auto [lo, hi] = scores.equal_range("Alice"); // ๋ฉค๋ฒ ํจ์ โ O(log n)
for (auto it = lo; it != hi; ++it) {
std::cout << it->first << ": " << it->second << "\n";
// Alice: 90 / Alice: 85 / Alice: 95
}
โ multimap/multiset์์ ๊ฐ์ ํค ๋ชจ๋ ๊ฐ์ ธ์ค๋ ์ ์ผํ ์ ์ ๋ฐฉ๋ฒ (๋ฐ๋ณต find๋ก๋ ์ฒซ ๊ฐ๋ง). โ ๋ฉค๋ฒ ํจ์ equal_range๊ฐ ๋ฐ๋ก ์๋ค โ ์๊ณ ๋ฆฌ์ฆ std::equal_range๋ณด๋ค ์๋ฃ๊ตฌ์กฐ ์นํ์ .
๋ชป ์ฐพ์์ ๋ โ .first == .second ์ ์๋ฏธ
1
2
3
4
5
std::vector<int> v = {1, 3, 5, 7};
auto [lo, hi] = std::equal_range(v.begin(), v.end(), 4);
// lo == hi (๋ ๋ค 5 ์์น, ์ธ๋ฑ์ค 2๋ฅผ ๊ฐ๋ฆฌํด)
// distance(lo, hi) == 0 โ 4๋ ์์
// ๊ทธ ์๋ฆฌ๊ฐ ์ ๋ ฌ ์ ์ง ์ฝ์
์์น
โ โ์ฐพ์ง ๋ชปํ ์์น = ์ ๋ ฌ ์ ์ง ์ฝ์ ์์นโ๋ผ๋ lower_bound์ ์ฑ์ง์ด ๊ทธ๋๋ก ์ ์ง๋จ.
lower_bound + upper_bound ๋ฐ๋ก ํธ์ถ vs equal_range
1
2
3
4
5
6
// (A) ๋ฐ๋ก ํธ์ถ โ ํธ๋ฆฌ/์ด๋ถ ํ์ 2๋ฒ
auto lo = std::lower_bound(v.begin(), v.end(), 2);
auto hi = std::upper_bound(v.begin(), v.end(), 2);
// (B) equal_range โ ํ ๋ฒ์
auto [lo, hi] = std::equal_range(v.begin(), v.end(), 2);
โ ํ์ค์ (B)๋ฅผ ๋จ์ผ ํจ์ค๋ก ์ต์ ํ ๊ฐ๋ฅํ๊ฒ ๋ช
์ธ โ ์ผ๋ถ ๊ตฌํ์ ๋ถ๊ธฐ ์ ์ฝ. ์๋ ํํ๋ ๋ช
ํ. โ โ๋ฒ์๊ฐ ํ์ํ๋คโ๊ฐ ์๋๋ฉด equal_range ์ง์ ํ.
๋ฐํ๊ฐ ์ ๋ฆฌ ์นด๋
1
2
3
4
5
6
7
equal_range(๋ฒ์, value) โ pair<It, It>
โโ .first = lower_bound โ value ์ด์ ์ฒซ ์์น
โโ .second = upper_bound โ value ์ด๊ณผ ์ฒซ ์์น
โโ [first, second) โ value์ ๋์น์ธ ์์ ์ ์ฒด
โโ distance(first, second) โ value์ ๊ฐ์
โโ first == second โ ์์ + ๊ทธ ์๋ฆฌ๊ฐ ์ฝ์
์์น
โโ multi์ปจํ
์ด๋์์ ํต์ฌ โ ๊ฐ์ ํค ์ ์ฒด ๊ฐ์ ธ์ค๊ธฐ
์ธ๋ฆฌ์ผ ๋์
์ธ๋ฆฌ์ผ์ Algo:: ๋ค์์คํ์ด์ค์ EqualRange๊ฐ ์๊ฑฐ๋ ๋งค์ฐ ์ ํ์ ์ด๋ผ ๋ณดํต ์ง์ ์กฐํฉ:
1
2
3
4
5
6
7
8
TArray<int32> Arr = {1, 2, 2, 2, 3, 4};
int32 Lo = Algo::LowerBound(Arr, 2); // 1
int32 Hi = Algo::UpperBound(Arr, 2); // 4
int32 Count = Hi - Lo; // 3
// TMultiMap์ ๋์น ํค ๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ
TArray<FValue> Values;
MultiMap.MultiFind(Key, Values); // ๋ฉค๋ฒ ํจ์ โ equal_range ๋์
โ ์ธ๋ฆฌ์ผ์์๋ MultiFind / LowerBound+UpperBound ์กฐํฉ์ด ์ปจ๋ฒค์
.
10. ๋ณด๊ฐ โ ํฐ ๋ฐ์ดํฐ์์ find vs binary_search ์ ํ
โํฐ ๋ฐ์ดํฐ๋ฉด ๋ฌด์กฐ๊ฑด binary_search๊ฐ ๋ซ์ง ์๋?โ๋ ์ ๋ฐ๋ง ๋ง๋ ๋ต์ ๋๋ค. ์ ๋ ฌ ๋น์ฉยท์กฐํ ํ์ยท์บ์ ์นํ์ฑ์ด ์์ต์ ๊ฐ๋ฆ ๋๋ค. ๋ฐ์ดํฐ๊ฐ ํด์๋ก ์คํ๋ ค ๋ค์ฏ ๊ฐ์ง ๋ณ์๋ฅผ ๋ฐ์ ธ์ผ ํฉ๋๋ค.
10-1. ๊ฒฐ๋ก ๋ถํฐ โ 5๊ฐ์ง ์๋๋ฆฌ์ค
| ์ํฉ | ์ ๋ต | ์ด์ |
|---|---|---|
| ์ด๋ฏธ ์ ๋ ฌ๋ผ ์์ + ๋จ๋ฐ ์กฐํ | binary_search / lower_bound | ์ ๋ ฌ ๋น์ฉ 0, O(log n) ๊ทธ๋๋ก ์ด๋ |
| ์ ๋ ฌ ์ ๋จ + 1ํ ์กฐํ | find | ์ ๋ ฌ ๋น์ฉ O(n log n) > ํ์ ๋น์ฉ O(n). ์ ๋ ฌ์ ์ํด |
| ์ ๋ ฌ ์ ๋จ + kํ ๋ฐ๋ณต ์กฐํ | k๊ฐ ํฌ๋ฉด ์ ๋ ฌ+binary_search | ์์ต๋ถ๊ธฐ์ ์ k โณ log n ๋ถ๊ทผ |
| n์ด ๋งค์ฐ ํผ + ๋์์ฑยท์ฝ์ ์ฆ์ | unordered_set/map (ํด์) | ํ๊ท O(1). ๋น๋ ๋์ ์กฐํ๋ฉด ์๋ฃ๊ตฌ์กฐ ์์ฒด๋ฅผ ๋ฐ๊ฟ |
| n์ด ์์ (~์์ญ~์๋ฐฑ) | find | ์บ์ยท๋ถ๊ธฐ ์์ธก ํจ๊ณผ๋ก ์ ํ์ด ๋ ๋น ๋ฅผ ๋๋ ์์ |
10-2. ์์ต๋ถ๊ธฐ์ โ ์ ๋ ฌํด์ผ ์ด๋์ธ๊ฐ
์กฐํ๋ฅผ k๋ฒ ํ๋ค๊ณ ๊ฐ์ ํ๊ณ ๋ ์ ๋ต ๋น์ฉ์ ๋น๊ตํฉ๋๋ค.
1
2
(A) ๋งค๋ฒ find : k * O(n) = O(kยทn)
(B) ์ ๋ ฌ 1ํ + binary_search k๋ฒ : O(n log n) + k * O(log n)
(B) < (A) ๊ฐ ๋๋ ค๋ฉด ๋๋ต k > log n ์ผ ๋๋ถํฐ. n=10โถ์ด๋ฉด logโn โ 20 โ 20๋ฒ ๋๊ฒ ์กฐํํ๋ค๋ฉด ์ ๋ ฌ์ด ์ด๋. ๋ฐ๋๋ก ํ๋ ๋ฒ๋ง ์ฐพ๊ณ ๋๋๋ฉด ๊ทธ๋ฅ find๊ฐ ๋น ๋ฆ
๋๋ค.
1
2
3
4
5
6
7
// ์ ์ข์ ํจํด โ ํ ๋ฒ ์ฐพ์ ๊ฑด๋ฐ ์ ๋ ฌ๋ถํฐ ํจ
std::sort(v.begin(), v.end()); // O(n log n)
bool ok = std::binary_search(v.begin(), v.end(), x); // O(log n)
// ํฉ๊ณ O(n log n) > std::find์ O(n)
// ์ข์ ํจํด โ ์ผํ์ฑ์ด๋ฉด ๊ทธ๋ฅ find
auto it = std::find(v.begin(), v.end(), x); // O(n)
10-3. ์บ์ ์นํ์ฑ โ ์์ ๋ฐ์ดํฐ์์ ์ ํ์ด ๋น ๋ฅผ ์ ์๋ค
์๊ณ ๋ฆฌ์ฆ ๋ณต์ก๋์ ๋ณ๊ฐ๋ก ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด์ด ์ค์ ์๋๋ฅผ ๊ฐ๋ฅธ๋ค. ํฐ ๋ฐ์ดํฐ์์ ๋จ์ ๋น๊ต ํ์๋ง ๋ณด๋ฉด binary_search๊ฐ ์์น์ด์ง๋ง, ๋ฐ์ดํฐ๊ฐ ์์ L1/L2 ์บ์์ ๋ค ์ฌ๋ผ๊ฐ๋ ๊ฒฝ์ฐ์ ์ ํ์ด ๋ ๋น ๋ฅผ ์ ์์ต๋๋ค.
| ์ธก๋ฉด | ์ ํ ํ์ (find) | ์ด๋ถ ํ์ (binary_search) |
|---|---|---|
| ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ | ์์ฐจ โ prefetcher ํ์ฉ | ๋ฌด์์ ์ ํ โ ์บ์ ๋ฏธ์ค ๅค |
| ๋ถ๊ธฐ ์์ธก | ๋จ์ (!= last๋ง) | ๋ถ๊ธฐ ๅค (mid ๋น๊ต๋ง๋ค) |
| n์ด ์์ ๋ | ๋น ๋ฆ (์๋ฐฑ~์์ฒ ๋จ์) | ์ค๋ฒํค๋๊ฐ ์ด๋๋ณด๋ค ํผ |
| n์ด ํด ๋ | O(n) โ ์๋์ ์ผ๋ก ๋๋ฆผ | ์๋์ ์ผ๋ก ๋น ๋ฆ |
์์ต๋ถ๊ธฐ ์ฒด๊ฐ (๋๋ต):
- n < ์ฝ 64~128 โ ์ ํ์ด ๋ ๋น ๋ฅด๊ฑฐ๋ ๋น์ท (CPUยทํ์ ์ ๋ฐ๋ผ ๋ค๋ฆ)
- n > ์ฝ 1,000 โ ์ด๋ถ ํ์์ด ๋ช ํํ ์ด๋
- n > 100,000 โ ์ด๋ถ ์์น, ์ ํ์ ์ฌ์ค์ ๋ชป ์
โ ๊ทธ๋์ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์์ ๊ตฌ๊ฐ์์ ์ ํ์ผ๋ก ํด๋ฐฑํ๋ ํ์ด๋ธ๋ฆฌ๋ ์ ๋ ฌ(introsort + insertion sort)์ ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์ ์๋ฆฌ.
10-4. n์ด ์ ๋ง ํด ๋ โ ์๋ฃ๊ตฌ์กฐ๋ฅผ ์์ฌํ๋ผ
vector์์ binary_search ์นด๋๋ง ๋ง์ง์๊ฑฐ๋ฆฌ์ง ๋ง๊ณ , ์กฐํ๊ฐ ํต์ฌ ์ํฌ๋ก๋๋ผ๋ฉด ์๋ฃ๊ตฌ์กฐ ์์ฒด๋ฅผ ๋ฐ๊พธ๋ ๊ฒ ๋ณดํต ๋ ํฐ ์ฐจ์ด๋ฅผ ๋ง๋ญ๋๋ค.
| ์๋ฃ๊ตฌ์กฐ | ํ๊ท ์กฐํ | ๋น๊ณ |
|---|---|---|
์ ๋ ฌ๋ vector + binary_search | O(log n) | ์บ์ ์นํ์ , ๋ฉ๋ชจ๋ฆฌ ์ปดํฉํธ, ์ฝ์ ์ O(n) |
std::set / std::map (RB-Tree) | O(log n) | ์ฝ์ ยท์ญ์ O(log n), ๋ฉ๋ชจ๋ฆฌ ๋จํธํ |
std::unordered_set / unordered_map | ํ๊ท O(1) | ํด์. ๋ฐ์ดํฐ ๋งค์ฐ ํด ๋ 1์์ |
| ์ธ๋ถ ์์ธ (B-Tree, Trie) | ์ผ์ด์ค๋ณ | DBยทํ์ผ ์์คํ ยท๋ฌธ์์ด |
โ โ์ ๋ ฌ๋ vector + binary_searchโ๋ ๋ฉ๋ชจ๋ฆฌ ํจ์จ๊ณผ ์บ์ ์นํ์ฑ์ผ๋ก ์ข
์ข
set๋ณด๋ค ๋น ๋ฆ
๋๋ค. ์ ์ ๋ฐ์ดํฐ(ํ ๋ฒ ๋น๋ ํ ์กฐํ๋ง)์ ํนํ ์ ๋ฆฌ. โ ๋์ ์ฝ์
์ด ์ฆ์ผ๋ฉด unordered_set ๋๋ set ์ ํ.
10-5. ์ค์ ๊ฐ์ด๋ โ ์์ฌ๊ฒฐ์ ํ๋ฆ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ํ์์ด ํ์ํ๋ค
โ
โโโโโโโโโโโโโโโดโโโโโโโโโโโโโโ
๋ฐ์ดํฐ ์ ๋ ฌ๋จ? ์๋์ค
โ โ
์ โโโโโโโโโโโโดโโโโโโโโโโโ
โ ์กฐํ๊ฐ 1~๋ช ๋ฒ ์กฐํ๊ฐ ๋ง์(k > log n)
โ โ โ
โโโโโโโโโดโโโโโโโโ find ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ฐ๊ฟ ์ ์๋?
์์น ํ์? ์กด์ฌ๋ง? (O(n)) โ
โ โ โโโโโโโโโโโโโดโโโโโโโโโ
lower_bound binary_search ์ ์๋์ค
(O(log n)) (O(log n)) โ โ
unordered_set sort + binary_search
/map (O(1)) (O(n log n + k log n))
10-6. ์์ฃผ ํ๋ ์ค์
- โํฐ ๋ฐ์ดํฐ๋๊น ๋ฌด์กฐ๊ฑด binary_searchโ โ ์ ๋ ฌ ๋น์ฉ์ ๋นผ๋จน์. ์ ๋ ฌ ์ ๋ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ๋ง ์ฐพ์ ๊ฑฐ๋ฉด
find๊ฐ ์ ๋ต. vector์ ๋งค๋ฒsortํธ์ถํ๊ณbinary_searchโsort์์ฒด๊ฐ O(n log n).set์ด๋unordered_set์ ์ฒ์๋ถํฐ ์ฐ๋ ๊ฒ ๋ง์.list์binary_searchโ Random Access๊ฐ ์๋๋ผ ์ ํ๊ฐ O(n). ์ด๋ถ์ ์ด๋ 0.list์ ๊ทธ๋ฅfind.- ์ฐ๊ด ์ปจํ
์ด๋์ ์๊ณ ๋ฆฌ์ฆ
std::findโset/map::find๋ฉค๋ฒ ํจ์๊ฐ O(log n) ๋ณด์ฅ. ์๊ณ ๋ฆฌ์ฆstd::find๋ O(n)์ด๋ผ ์ํด ํผ.
10-7. ํ ์ค ์์ฝ
1
2
3
4
5
ํฐ ๋ฐ์ดํฐ + ์ ๋ ฌ๋จ โ binary_search (O(log n)) โ ์์น
ํฐ ๋ฐ์ดํฐ + ์ ๋ ฌ ์ ๋จ + 1ํ โ find (O(n)) โ ์ ๋ ฌ ๋น์ฉ ํํผ
ํฐ ๋ฐ์ดํฐ + ์ ๋ ฌ ์ ๋จ + ๋คํ โ sort + binary_search โ k > log n์์ ์ด๋
๊ฑฐ๋ ๋ฐ์ดํฐ + ์กฐํ ๋น๋ฒ โ unordered_set/map (O(1)) โ ์๋ฃ๊ตฌ์กฐ ๊ต์ฒด๊ฐ ์ ๋ต
์์ ๋ฐ์ดํฐ (~์๋ฐฑ) โ find๋ ์ถฉ๋ถ (์บ์ยท๋ถ๊ธฐ ์์ธก ์ด์ )
โ ํต์ฌ์ โ์ ๋ ฌ ๋น์ฉ + ์กฐํ ๋น์ฉโ์ ํฉ์ณ์ ๋น๊ตํ ๊ฒ, ๊ทธ๋ฆฌ๊ณ ์ง์ง ํฐ ๋ฐ์ดํฐ๋ฉด ์๋ฃ๊ตฌ์กฐ ์์ฒด๋ฅผ ์์ฌํ ๊ฒ.
์ ๋ฆฌ โ ์ธ์ ๋ฌด์์ ์ฐ๋
1
2
3
4
5
6
์ ๋ ฌ ์ ๋๊ฑฐ๋, ์ผํ์ฑ, equality ๋น๊ต ์ถฉ๋ถ โ std::find
์ ๋ ฌ๋๊ณ , ์กด์ฌ ์ฌ๋ถ๋ง ํ์ โ std::binary_search
์ ๋ ฌ๋๊ณ , ์์น๊น์ง ํ์ โ std::lower_bound (+ *it == value ๊ฒ์ฌ)
์ ๋ ฌ๋๊ณ , ๊ฐ์ ๊ฐ ๋ฒ์(์ค๋ณต ๋คํ) ํ์ โ std::equal_range
์ ๋ ฌ ์ ์ง ์ฝ์
โ std::lower_bound + insert
์ฐ๊ด ์ปจํ
์ด๋ (set/map/unordered_*) โ ๋ฉค๋ฒ ํจ์ .find() โ
์๊ณ ๋ฆฌ์ฆ X
ํต์ฌ ์์ฝ ์นด๋ (์ฌ๊ฒ์ฌ)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::find โ O(n), iterator, ์ ๋ ฌ X, == | ๋ชป ์ฐพ์ผ๋ฉด end()
std::binary_search โ O(log n), bool, ์ ๋ ฌ โ
, <๋ ๋ฒ | ์์น ๋ชจ๋ฆ
โ ์์น๊น์ง ํ์ํ๋ฉด
std::lower_bound โ O(log n), iterator (binary_search ๋ด๋ถ)
| ๋ชป ์ฐพ์๋ end()๊ฐ ์๋ ์ ์์ โ *it == value ์ถ๊ฐ ๊ฒ์ฌ
iterator = ์ปจํ
์ด๋ ์์๋ฅผ ๊ฐ๋ฆฌํค๋ ์ถ์ ํฌ์ธํฐ. *it / ++it / it==end 3์ข
end()๋ past-the-end (์ ํจ ์์ ์๋). [first, last) ๋ฐ์ด๋ฆฐ ๊ตฌ๊ฐ.
๋์น(equivalence) = !(a<b)&&!(b<a). ==๊ณผ ๋ค๋ฆ. < ๋ง ์ ์๋๋ฉด OK (strict weak ordering)
set/map โ ๋ฉค๋ฒ ํจ์ find() (O(log n))
unordered_map โ ๋ฉค๋ฒ ํจ์ find() (O(1) ํ๊ท )
์๊ณ ๋ฆฌ์ฆ std::find์ ์ฐ๊ด ์ปจํ
์ด๋์ ์ฐ๋ฉด ์ํด (O(n))
์ธ๋ฆฌ์ผ: Algo::Find (T*), Algo::BinarySearch (int32 / INDEX_NONE),
TArray::Find (๋ฉค๋ฒ, int32)