Skip to content

Commit 620ee16

Browse files
committed
[cpp][15_bsearch] done.
1 parent 7267957 commit 620ee16

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

c-cpp/15_bsearch/bsearch.hpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Created by Liam Huang (Liam0205) on 2018/10/24.
3+
*/
4+
5+
#ifndef BSEARCH_BSEARCH_HPP_
6+
#define BSEARCH_BSEARCH_HPP_
7+
8+
#include <iterator>
9+
#include <functional>
10+
11+
enum class BsearchPolicy { FIRST, LAST, UNSPECIFIED };
12+
13+
template <typename IterT,
14+
typename ValueT = typename std::iterator_traits<IterT>::value_type,
15+
typename Compare = std::less<ValueT>>
16+
IterT bsearch(IterT first,
17+
IterT last,
18+
ValueT target,
19+
Compare comp,
20+
BsearchPolicy policy = BsearchPolicy::UNSPECIFIED) {
21+
IterT result = last;
22+
while (std::distance(first, last) > 0) {
23+
IterT mid = first + std::distance(first, last) / 2;
24+
if (comp(*mid, target)) {
25+
first = mid + 1;
26+
} else if (comp(target, *mid)) {
27+
last = mid;
28+
} else { // equal
29+
if (policy == BsearchPolicy::FIRST) {
30+
if (mid == first or comp(*(mid - 1), *mid)) {
31+
result = mid;
32+
break;
33+
} else {
34+
last = mid;
35+
}
36+
} else if (policy == BsearchPolicy::LAST) {
37+
if (std::distance(mid, last) == 1 or comp(*mid, *(mid + 1))) {
38+
result = mid;
39+
break;
40+
} else {
41+
first = mid + 1;
42+
}
43+
} else {
44+
result = mid;
45+
break;
46+
}
47+
}
48+
}
49+
return result;
50+
}
51+
52+
template <typename IterT,
53+
typename ValueT = typename std::iterator_traits<IterT>::value_type>
54+
IterT bsearch(IterT first,
55+
IterT last,
56+
ValueT target,
57+
BsearchPolicy policy = BsearchPolicy::UNSPECIFIED) {
58+
return bsearch(first, last, target, std::less<ValueT>(), policy);
59+
}
60+
61+
#endif // BSEARCH_BSEARCH_HPP_
62+

c-cpp/15_bsearch/bsearch_test.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Created by Liam Huang (Liam0205) on 2018/10/24.
3+
*/
4+
5+
#include <iostream>
6+
#include <vector>
7+
8+
#include "bsearch.hpp"
9+
10+
template <typename VecT, typename T = typename VecT::value_type>
11+
void test_bsearch(const VecT& test,
12+
T target,
13+
BsearchPolicy policy = BsearchPolicy::UNSPECIFIED) {
14+
auto it = bsearch(test.begin(), test.end(), target, policy);
15+
std::cout << std::distance(test.begin(), it) << std::endl;
16+
}
17+
18+
int main() {
19+
std::vector<int> test{0, 0, 1, 2, 3, 4, 4, 5, 5, 5, 5, 5, 6, 7}; // std::less<int>()
20+
21+
test_bsearch(test, 8); // 14
22+
test_bsearch(test, -1); // 14
23+
test_bsearch(test, 0); // 0, 1
24+
test_bsearch(test, 0, BsearchPolicy::FIRST); // 0
25+
test_bsearch(test, 0, BsearchPolicy::LAST); // 1
26+
test_bsearch(test, 4); // 5, 6
27+
test_bsearch(test, 4, BsearchPolicy::FIRST); // 5
28+
test_bsearch(test, 4, BsearchPolicy::LAST); // 6
29+
test_bsearch(test, 5); // 7, 8, 9, 10, 11
30+
test_bsearch(test, 5, BsearchPolicy::FIRST); // 7
31+
test_bsearch(test, 5, BsearchPolicy::LAST); // 11
32+
test_bsearch(test, 7); // 13
33+
test_bsearch(test, 7, BsearchPolicy::FIRST); // 13
34+
test_bsearch(test, 7, BsearchPolicy::LAST); // 13
35+
36+
return 0;
37+
}
38+

0 commit comments

Comments
 (0)