Skip to content

Commit 0007299

Browse files
algorithm: partition_point と *_bound に実装例を追加
また、*bound が partition_point と本質的に同一であることを記載。
1 parent 45b9985 commit 0007299

3 files changed

Lines changed: 146 additions & 5 deletions

File tree

reference/algorithm/lower_bound.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ namespace std {
2727
最大で log2(`last - first`) + O(1) 回の比較を行う
2828
2929
30+
##備考
31+
本関数は、本質的に C++11 で追加された [`partition_point`](partition_point.md) と同一である。
32+
具体的には、[`partition_point`](partition_point.md)`(first, last, [value](const T& e) { return e < value; })`、あるいは、[`partition_point`](partition_point.md)`(first, last, [value, comp](const T& e) { return comp(e, value); })` とすることで同一の結果が得られる。
33+
34+
3035
##例
3136
```cpp
3237
#include <iostream>
@@ -46,10 +51,62 @@ int main()
4651
}
4752
```
4853
* lower_bound[color ff0000]
54+
* iostream[link ../iostream.md]
55+
* vector[link ../vector.md]
56+
* algorithm[link ../algorithm.md]
57+
* sort[link sort.md]
58+
* begin[link ../vector/begin.md]
59+
* end[link ../vector/end.md]
60+
* cout[link ../iostream/cout.md]
61+
* endl[link ../ostream/endl.md]
62+
4963

5064
###出力
5165
```
5266
3
5367
```
5468

5569

70+
##実装例
71+
```cpp
72+
template<class ForwardIterator, class T>
73+
ForwardIterator
74+
lower_bound(ForwardIterator first, ForwardIterator last, const T& value)
75+
{
76+
typedef typename std::iterator_traits<ForwardIterator>::difference_type diff;
77+
for (diff len = std::distance(first, last); len != 0; ) {
78+
diff half = len / 2;
79+
ForwardIterator mid = first;
80+
std::advance(mid, half);
81+
if (*mid < value) {
82+
len -= half + 1;
83+
first = ++mid;
84+
} else {
85+
len = half;
86+
}
87+
}
88+
return first;
89+
}
90+
91+
template<class ForwardIterator, class T, class Compare>
92+
ForwardIterator
93+
lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp)
94+
{
95+
typedef typename std::iterator_traits<ForwardIterator>::difference_type diff;
96+
for (diff len = std::distance(first, last); len != 0; ) {
97+
diff half = len / 2;
98+
ForwardIterator mid = first;
99+
std::advance(mid, half);
100+
if (comp(*mid, value)) {
101+
len -= half + 1;
102+
first = ++mid;
103+
} else {
104+
len = half;
105+
}
106+
}
107+
return first;
108+
}
109+
```
110+
* distance[link ../iterator/distance.md]
111+
* advance[link ../iterator/advance.md]
112+
* iterator_traits[link ../iterator/iterator_traits.md]

reference/algorithm/partition_point.md

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@ O(log(`last - first`)) のオーダーで `pred` が適用される。
3030
#include <iostream>
3131
#include <vector>
3232
#include <algorithm>
33-
#include <string>
3433
35-
void print(const std::string& name, const std::vector<int>& v)
34+
void print(const char* name, const std::vector<int>& v)
3635
{
3736
std::cout << name << " : ";
3837
std::for_each(v.begin(), v.end(), [](int x) {
@@ -57,6 +56,15 @@ int main()
5756
}
5857
```
5958
* partition_point[color ff0000]
59+
* vector[link ../vector.md]
60+
* iostream[link ../iostream.md]
61+
* algorithm[link ../algorithm.md]
62+
* for_each[link for_each.md]
63+
* begin[link ../vector/begin.md]
64+
* end[link ../vector/end.md]
65+
* partition[link partition.md]
66+
* cout[link ../iostream/cout.md]
67+
* endl[link ../ostream/endl.md]
6068

6169

6270
###出力
@@ -65,6 +73,29 @@ v : 4,2,3,1,5,
6573
3
6674
```
6775

76+
##実装例
77+
```cpp
78+
template<class ForwardIterator, class Predicate>
79+
ForwardIterator
80+
partition_point(ForwardIterator first, ForwardIterator last, Predicate pred)
81+
{
82+
for (auto len = std::distance(first, last); len != 0; ) {
83+
auto half = len / 2;
84+
auto mid = std::next(first, half);
85+
if (pred(*mid)) {
86+
len -= half + 1;
87+
first = std::next(mid);
88+
} else {
89+
len = half;
90+
}
91+
}
92+
return first;
93+
}
94+
```
95+
* distance[link ../iterator/distance.md]
96+
* next[link ../iterator/next.md]
97+
98+
6899
##バージョン
69100
###言語
70101
- C++11
@@ -76,6 +107,3 @@ v : 4,2,3,1,5,
76107
- [GCC, C++0x mode](/implementation.md#gcc): 4.7.0
77108
- [ICC](/implementation.md#icc): ??
78109
- [Visual C++](/implementation.md#visual_cpp) ??
79-
80-
81-

reference/algorithm/upper_bound.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ namespace std {
2727
最大で log2(`last - first`) + O(1) 回の比較を行う
2828
2929
30+
##備考
31+
本関数は、本質的に C++11 で追加された [`partition_point`](partition_point.md) と同一である。
32+
具体的には、[`partition_point`](partition_point.md)`(first, last, [value](const T& e) { return !bool(value < e); })`、あるいは、[`partition_point`](partition_point.md)`(first, last, [value, comp](const T& e) { return !bool(comp(value, e)); })` とすることで同一の結果が得られる。
33+
34+
3035
##例
3136
```cpp
3237
#include <iostream>
@@ -46,6 +51,14 @@ int main()
4651
}
4752
```
4853
* upper_bound[color ff0000]
54+
* iostream[link ../iostream.md]
55+
* vector[link ../vector.md]
56+
* algorithm[link ../algorithm.md]
57+
* sort[link sort.md]
58+
* begin[link ../vector/begin.md]
59+
* end[link ../vector/end.md]
60+
* cout[link ../iostream/cout.md]
61+
* endl[link ../ostream/endl.md]
4962

5063

5164
###出力
@@ -54,3 +67,46 @@ int main()
5467
```
5568

5669

70+
##実装例
71+
```cpp
72+
template<class ForwardIterator, class T>
73+
ForwardIterator
74+
upper_bound(ForwardIterator first, ForwardIterator last, const T& value)
75+
{
76+
typedef typename std::iterator_traits<ForwardIterator>::difference_type diff;
77+
for (diff len = std::distance(first, last); len != 0; ) {
78+
diff half = len / 2;
79+
ForwardIterator mid = first;
80+
std::advance(mid, half);
81+
if (!bool(value < *mid)) {
82+
len -= half + 1;
83+
first = ++mid;
84+
} else {
85+
len = half;
86+
}
87+
}
88+
return first;
89+
}
90+
91+
template<class ForwardIterator, class T, class Compare>
92+
ForwardIterator
93+
upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp)
94+
{
95+
typedef typename std::iterator_traits<ForwardIterator>::difference_type diff;
96+
for (diff len = std::distance(first, last); len != 0; ) {
97+
diff half = len / 2;
98+
ForwardIterator mid = first;
99+
std::advance(mid, half);
100+
if (!bool(comp(value, *mid))) {
101+
len -= half + 1;
102+
first = ++mid;
103+
} else {
104+
len = half;
105+
}
106+
}
107+
return first;
108+
}
109+
```
110+
* distance[link ../iterator/distance.md]
111+
* advance[link ../iterator/advance.md]
112+
* iterator_traits[link ../iterator/iterator_traits.md]

0 commit comments

Comments
 (0)