Top 5 Beautiful C++ std Algorithms Examples
2014-12-25 16:59
169 查看
原文链接:http://www.codeproject.com/Articles/854127/Top-Beautiful-Cplusplus-std-Algorithms-Examples
原作者:Bartlomiej Filipek
Some time ago, I saw an inspiring talk from CppCon 2013:
"C++ Seasoning" by Sean Parent. One of the main points of this presentation was
not to use raw loops. Instead, prefer to use existing algorithms or write functions that 'wraps' such loops. I was curious about this idea and searched for nice code examples. Here is my short list of usage of algorithms from the C++
Of course. I could not skip two prominent examples from the original "C++ Seasoning" talk:
slide and gather.
Quick sort
Slide
Gather
String trim
Bonus
Sumup
Resources
beautiful_std_alg.cpp @github
Solution (VS2013) is located here:
vc_solution @github
How do those two elements combine into Insertion sort?
Let's look at one example:
Pretty nice!
Stack Overflow:
This function uses
It returns two iterators - the start and the end of the new sequence. In C++11
If you are not interested in returning of this iterator pair, you can simplify this code much more.
Implementation note:
In GCC 4.9 (and previous versions)
cppreference
Reorders the elements in a given range in such a way that all elements for which the predicate returns
Implementation note:
here in Sean's comment.
In order to trim the
trim left:
trim right: also uses
Note: You can also use
boost string algorithm to make life even easier.
Bonus
What does this code do?
Simple, one line of code... should be nice! But...
Answer: It's another and 'wonderful' method of sorting containers - permutation sort! But please do not use it at home.
Complexity: O((n+1)!)
This algorithm is a variation of Bogosort and other similar 'sorting' algorithms.
Read more on wiki. As victor_zverovich noticed, in Bogosort the next permutation is chosen at random, but
called instead.
Do you know some more interesting examples? My list, definitely, does not show all of them!
C++ Seasoning, by Sean Paret @Channel9 - original inspiration for this article
The C++ Programming Language, 4th
The C++ Standard Library: A Tutorial and Reference
(2nd Edition)
SO: How to implement classic sorting algorithms in modern C++? - very detailed answer with nice code for modern C++
SO: What's the best way to trim std::string
10 New STL Algorithms That Will Make You A More Productive Developer, C++0x
The Code Project Open License (CPOL)
原作者:Bartlomiej Filipek
Some time ago, I saw an inspiring talk from CppCon 2013:
"C++ Seasoning" by Sean Parent. One of the main points of this presentation was
not to use raw loops. Instead, prefer to use existing algorithms or write functions that 'wraps' such loops. I was curious about this idea and searched for nice code examples. Here is my short list of usage of algorithms from the C++
stdlibrary that might help in writing better code.
Of course. I could not skip two prominent examples from the original "C++ Seasoning" talk:
slide and gather.
The Plan
Insertion sortQuick sort
Slide
Gather
String trim
Bonus
Sumup
Resources
The Code
Source code can be found here:beautiful_std_alg.cpp @github
Solution (VS2013) is located here:
vc_solution @github
Insertion Sort
In just two lines of code!<code>for (auto i = start; i != end; ++i) std::rotate(std::upper_bound(start, i, *i), i, std::next(i));
How It Works?
Rotate(first, middle, last)- takes a range
[first, last)and rotates it so that the
middleelement becomes the first in that range.
upper_bound- Returns an iterator pointing to the first element in the range
[first,last)which compares greater than
val. The range should be already sorted (or at least partitioned).
How do those two elements combine into Insertion sort?
std::upper_bound(start, i, *i)returns position of the first element greater than
*i. Then, the range is shifted, so that
i-thelement becomes first.
Let's look at one example:
Pretty nice!
Quick Sort
Found onStack Overflow:
<code>template<class FwdIt, class Compare = std::less<>> void quickSort(FwdIt first, FwdIt last, Compare cmp = Compare{}) { auto const N = std::distance(first, last); if (N <= 1) return; auto const pivot = std::next(first, N / 2); std::nth_element(first, pivot, last, cmp); quickSort(first, pivot, cmp); quickSort(pivot, last, cmp); }
How It Works?
I will not describe quick sort algorithm... you should know how it works already! In this implementation,std::nth_elementis used to do most of the job. This function partially sorts the range so that given
n-thelements is placed in proper position. All of the elements before
n-thelement are less than or equal to the elements after the
n-thelement.
Slide
Example from the Sean Parent's talk:<code>template <typename It> auto slide(It f, It l, randIter p) -> std::pair<It, It> { if (p < f) return { p, std::rotate(p, f, l) }; if (l < p) return { std::rotate(f, l, p), p }; return { f, l }; }
How It Works?
As an example, you can imagine a list of items on a UI dialog. User selects a continuous range and then algorithm takes this range and moves it into some other place of the list.This function uses
std::rotate: to move elements forward or backward.
It returns two iterators - the start and the end of the new sequence. In C++11
std::rotategot new version and now can return iterator to the new position of
pelement.
If you are not interested in returning of this iterator pair, you can simplify this code much more.
Implementation note:
In GCC 4.9 (and previous versions)
std::rotatedoes not return an iterator, but only
void. So currently, this code will not work there.
Gather
Another example from Sean Parent's talk:<code>template <typename BiIt, typename UnPred> auto gather(BiIt f, BiIt l, BiIt p, UnPred s) -> std::pair <BiIt, BiIt> { return { stable_partition(f, p, not1(s)), stable_partition(p, l, s) }; }
How It Works?
Its use case can be similar toslide: select elements - using a predicate
s(so this time continuous range is not needed), then gather those elements into a range and move this range to position around
p. It returns the start and the end of the selected range.
UnPredis a predicate that returns if a given element is selected or not.
std::stable_partition: from
cppreference
Reorders the elements in a given range in such a way that all elements for which the predicate returns
trueprecede the elements for which predicate returns
false. Relative order of the elements is preserved.
std::stable_partitionis used twice:
Implementation note:
std::not1does not work with the code correctly, so there is a proposal to use simple lambda. Read more
here in Sean's comment.
String trim
Found on Stack Overflow<code>std::string trim(const std::string &s) { return trimLeft(trimRight(s)); } std::string trimLeft(const std::string &s) { auto temp = s; temp.erase(std::begin(temp), std::find_if(std::begin(temp), std::end(temp), [](char c){return !std::isspace(c, std::locale()); })); return temp; } std::string trimRight(const std::string &s) { auto temp = s; temp.erase(std::find_if(std::rbegin(temp), std::rend(temp), [](char c){return !std::isspace(c, std::locale()); }).base(), std::end(temp)); return temp; }
How It Works?
Another beautiful usage of Standard Library:In order to trim the
string, we trim from right and then from the left (what a discovery!)
trim left:
std::find_ifreturns iterator to the first non space character in the
string. Then we erase those characters.
trim right: also uses
std::find_ifbut this time we use reverse iterators
Note: You can also use
boost string algorithm to make life even easier.
Bonus
What does this code do?<code>while (std::next_permutation(start, end));
Simple, one line of code... should be nice! But...
Answer: It's another and 'wonderful' method of sorting containers - permutation sort! But please do not use it at home.
Complexity: O((n+1)!)
This algorithm is a variation of Bogosort and other similar 'sorting' algorithms.
Read more on wiki. As victor_zverovich noticed, in Bogosort the next permutation is chosen at random, but
std::next_permutationgives the next lexicographically greater permutation.
Sumup
I've showed several, I think nice, code examples where algorithms from C++ Standard Library are heavily used. Maybe next time, when I'll be writing some ugly piece of code I'll stop, think for a minute, and maybe some existing algorithm/function could becalled instead.
Do you know some more interesting examples? My list, definitely, does not show all of them!
Resources
C++ Seasoning, by Sean Paret @Channel9 - original inspiration for this article
The C++ Programming Language, 4th
The C++ Standard Library: A Tutorial and Reference
(2nd Edition)
SO: How to implement classic sorting algorithms in modern C++? - very detailed answer with nice code for modern C++
SO: What's the best way to trim std::string
10 New STL Algorithms That Will Make You A More Productive Developer, C++0x
License
This article, along with any associated source code and files, is licensed underThe Code Project Open License (CPOL)
相关文章推荐
- VS2005:C++ std::string, std::wstring转换方法
- C++ and STL: Take Advantage of STL Algorithms by Implementing a Custom Iterator
- C++ Arrays and Algorithms
- C/C++字符串处理(4):std::vector与std::StringBuilder
- 慎用C++ std::map 的[]运算符
- C++ using namespace std 详解
- VS2005:C++ std::string, std::wstring转换方法
- C/C++字符串处理(4):std::vector与std::StringBuilder
- C/C++字符串处理(4):std::vector与std::StringBuilder
- 想翻译Memory Management Algorithms and Implementation in c/c++
- 用C++ std::priority_queue 实现哈夫曼算法
- VS2005:C++ std::string, std::wstring转换方法
- c++ 中int转换为std::string
- top 10 algorithms in data mining
- VS2005:C++ std::string, std::wstring转换方法
- c++代码测试-std::string元素
- 在高性能计算中慎用C++ std::complex
- std空间声明的具体地方 和 标准C++有时间函数吗?
- C/C++字符串处理:std::vector与std::StringBuilder
- C++ using namespace std 详解