1- /*
2- # algorithm
3- */
4-
51#include " common.hpp"
62
73int main () {
@@ -25,22 +21,21 @@ int main() {
2521 assert ((v == std::vector<int >{1 , 0 , 2 }));
2622 }
2723
28- /*
29- # swap
30-
31- Does things equivalent to:
32-
33- template <class T> void swap (T& a, T& b)
34- {
35- T c(a); a=b; b=c;
36- }
37-
38- However stdlib can specialize it to do operations more efficiently.
39-
40- Some stdlib classes implement swap as a method.
41-
42- Particularly important because of the copy and swap idiom.
43- */
24+ /* # swap
25+ *
26+ * Does things equivalent to:
27+ *
28+ * template <class T> void swap (T& a, T& b)
29+ * {
30+ * T c(a); a=b; b=c;
31+ * }
32+ *
33+ * However stdlib can specialize it to do operations more efficiently.
34+ *
35+ * Some stdlib classes implement swap as a method.
36+ *
37+ * Particularly important because of the copy and swap idiom.
38+ */
4439
4540 // # randomize
4641 {
@@ -56,24 +51,22 @@ int main() {
5651 assert (v2 == std::vector<int >({3 , 2 , 0 , 1 , 3 }));
5752 }
5853
59- /*
60- # equal
61-
62- Compares ranges of two containers.
63- */
54+ /* # equal
55+ *
56+ * Compares ranges of two containers.
57+ */
6458 {
6559 std::vector<int > v {0 , 1 , 2 };
6660 std::vector<int > v2{ 1 , 2 , 3 };
6761 assert (std::equal (v.begin () + 1 , v.end (), v2.begin ()));
6862 }
6963
70- /*
71- # accumulate
72-
73- Sum over range with operator+
74-
75- Also has functional versions http://www.cplusplus.com/reference/numeric/accumulate/
76- */
64+ /* # accumulate
65+ *
66+ * Sum over range with operator+
67+ *
68+ * Also has functional versions http://www.cplusplus.com/reference/numeric/accumulate/
69+ */
7770 {
7871 {
7972 std::vector<int > v{2 , 0 , 1 };
@@ -89,11 +82,10 @@ int main() {
8982 }
9083 }
9184
92- /*
93- # find
94-
95- Return iterator to first found element.
96- */
85+ /* # find
86+ *
87+ * Return iterator to first found element.
88+ */
9789 {
9890 std::vector<int > v{2 ,0 ,1 };
9991 unsigned int pos;
@@ -111,29 +103,27 @@ int main() {
111103 assert (pos == v.size ());
112104 }
113105
114- /*
115- # find_if
116-
117- Like find, but using an arbitrary condition on each element instead of equality.
118-
119- Consider usage with C++11 lambdas and functional.
120- */
106+ /* # find_if
107+ *
108+ * Like find, but using an arbitrary condition on each element instead of equality.
109+ *
110+ * Consider usage with C++11 lambdas and functional.
111+ */
121112 {
122113 std::vector<int > v{2 , 0 , 1 };
123114 assert (std::find_if (v.begin (), v.end (), odd) == --v.end ());
124115 }
125116
126- /*
127- # binary_search
128-
129- Container must be already sorted.
130-
131- Log complexity.
132-
133- Only states if the element is present or not, but does not get its position.
134-
135- If you want to get the position of those items, use `equal_range`, `lower_bound` or `upper_bound`.
136- */
117+ /* # binary_search
118+ *
119+ * Container must be already sorted.
120+ *
121+ * Log complexity.
122+ *
123+ * Only states if the element is present or not, but does not get its position.
124+ *
125+ * If you want to get the position of those items, use `equal_range`, `lower_bound` or `upper_bound`.
126+ */
137127 {
138128
139129 std::vector<int > v{0 , 1 , 2 };
@@ -142,37 +132,34 @@ int main() {
142132 assert (std::binary_search (v.begin (), v.end () - 1 , 2 ) == false );
143133 }
144134
145- /*
146- # lower_bound
147-
148- Finds first element in container which is not less than val.
149- */
135+ /* # lower_bound
136+ *
137+ * Finds first element in container which is not less than val.
138+ */
150139 {
151140 std::vector<int > v{0 , 2 , 3 };
152141 auto it = std::lower_bound (v.begin (), v.end (), 1 );
153142 assert (it - v.begin () == 1 );
154143 }
155144
156- /*
157- # upper_bound
158-
159- Finds first element in container is greater than val.
160- */
145+ /* # upper_bound
146+ *
147+ * Finds first element in container is greater than val.
148+ */
161149 {
162150 std::vector<int > v{0 , 1 , 2 };
163151 auto it = std::upper_bound (v.begin (), v.end (), 1 );
164152 assert (it - v.begin () == 2 );
165153 }
166154
167- /*
168- # equal_range
169-
170- Finds first and last location of a value iniside a ranged container.
171-
172- Return values are the same as lower_bound and upper_bound.
173-
174- log complexity.
175- */
155+ /* # equal_range
156+ *
157+ * Finds first and last location of a value iniside a ranged container.
158+ *
159+ * Return values are the same as lower_bound and upper_bound.
160+ *
161+ * log complexity.
162+ */
176163 {
177164 std::vector<int > v{0 , 1 , 1 , 2 };
178165 std::vector<int >::iterator begin, end;
@@ -197,20 +184,19 @@ int main() {
197184 assert (*std::min_element (v.begin (), v.end ()) == 0 );
198185 }
199186
200- /*
201- # advance
202-
203- Advance iterator by given number.
204-
205- If random access, simply adds + N.
206-
207- Else, calls `++` N times.
208-
209- Advantage over `+`: only random access containers support `+`,
210- but this works for any container, allowing one to write more general code.
211-
212- Beware however that this operation will be slow for non random access containers.
213- */
187+ /* # advance
188+ *
189+ * Advance iterator by given number.
190+ *
191+ * If random access, simply adds + N.
192+ *
193+ * Else, calls `++` N times.
194+ *
195+ * Advantage over `+`: only random access containers support `+`,
196+ * but this works for any container, allowing one to write more general code.
197+ *
198+ * Beware however that this operation will be slow for non random access containers.
199+ */
214200 {
215201 std::vector<int > v{0 , 1 , 2 };
216202 auto it = v.begin ();
@@ -219,11 +205,10 @@ int main() {
219205 }
220206
221207#if __cplusplus >= 201103L
222- /*
223- # next
224-
225- Same as advance, but returns a new iterator instead of modifying the old one.
226- */
208+ /* # next
209+ *
210+ * Same as advance, but returns a new iterator instead of modifying the old one.
211+ */
227212 {
228213 std::vector<int > v{0 , 1 , 2 };
229214 auto it (v.begin ());
@@ -232,125 +217,4 @@ int main() {
232217 assert (*itNext == 2 );
233218 }
234219#endif
235-
236- /*
237- # priority queue
238-
239- Offers `O(1)` access to the smalles element.
240-
241- Other operatoins vary between `O(n)` and `O(1).
242-
243- Most common implementaions are via:
244-
245- - binary heap
246- - fibonacci heap
247-
248- Boost offers explicit heap types: fibonacci, binary and others.
249-
250- But no guarantees are made.
251-
252- As of C++11, does not support the increase key operation.
253-
254- A binary heap without increase key can be implemented via the heap function family under algorithm.
255- */
256-
257- /*
258- # heap
259-
260- Binary heap implementation.
261-
262- <http://en.wikipedia.org/wiki/Heap_%28data_structure%29>
263-
264- In short:
265-
266- - getting largest element is O(1)
267- - removing the largest element is O(lg) for all implementation
268- - other operations (insertion) may be O(1) or O(lg) depending on the implementation.
269-
270- this makes for a good priority queue.
271- Exact heap type is not guaranteed. As of 2013, it seems that most implementations use binary heaps.
272-
273- For specific heaps such as Fibonacci, consider [Boost](http://www.boost.org/doc/libs/1_49_0/doc/html/heap.html).
274-
275- <http://stackoverflow.com/questions/14118367/stl-for-fibonacci-heap>
276-
277- There is no concrete heap data structure in C++:
278- only heap operations over random access data structures.
279- This is why this is under algoritms and is not a data structure of its own.
280-
281- There is however a `priority_queue` stdlib container.
282-
283- Why random access structure is needed: <https://github.com/cirosantilli/comp-sci/blob/1.0/src/heap.md#array-implementation>
284- */
285- {
286- int myints[]{10 , 20 , 30 , 5 , 15 };
287- std::vector<int > v (myints, myints + 5 );
288-
289- /*
290- # make_heap
291-
292- Make random access data structure into a heap.
293-
294- This changes the element order so that the range has heap properties
295-
296- Worst case time: $O(n)$.
297- */
298- std::make_heap (v.begin (), v.end ());
299- assert (v.front () == 30 );
300-
301- /*
302- # pop_heap
303-
304- Remove the largest element from the heap.
305-
306- That element is moved to the end of the data structure, but since the
307- heap should have its length reduced by one, that element will then be out of the heap.
308-
309- Assumes that the input range is already a heap (made with `make_heap` for example).
310- */
311- std::pop_heap (v.begin (), v.end ());
312-
313- // the element still exists on the data structure
314- assert (v.back () == 30 );
315-
316- // the second largest element hat become the largets
317- assert (v.front () == 20 );
318-
319- // remove the element from the data structure definitively
320- v.pop_back ();
321-
322- /*
323- # push_heap
324-
325- Insert element into a heap.
326-
327- Assumes that:
328-
329- - the range 0 - (end - 1) was already a heap
330- - the new element to be inserted into that heap is at end.
331- */
332-
333- // add the new element to the data structure
334- v.push_back (99 );
335-
336- // reorganize the data so that the last element will be placed in the heap
337- std::push_heap (v.begin (), v.end ());
338-
339- assert (v.front () == 99 );
340-
341- /*
342- # sort_heap
343-
344- Assumes that the input range is a heap, and sorts it in increasing order.
345-
346- The assumption that we have a heap allows for $O(ln)$ sorting,
347- much faster than the optimal bound $O(n log n)$.
348-
349- This is exactly what the heapsort alrotithm does: make_heap and then sort_heap.
350- */
351-
352- std::sort_heap (v.begin (), v.end ());
353- // assert(v)
354- // v == 5 10 15 20 99
355- }
356220}
0 commit comments