STL(14)变动型算法
Posted zzdoit
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL(14)变动型算法相关的知识,希望对你有一定的参考价值。
STL(14)变动型算法
- Modifying sequence operations: (修改容器操作)
copy
Copy range of elements (function template )
copy_n
Copy elements (function template )
copy_if
Copy certain elements of range (function template )
copy_backward
Copy range of elements backward (function template )
move
Move range of elements (function template )
move_backward
Move range of elements backward (function template )
swap
Exchange values of two objects (function template )
swap_ranges
Exchange values of two ranges (function template )
iter_swap
Exchange values of objects pointed to by two iterators (function template )
transform
Transform range (function template )
replace
Replace value in range (function template )
replace_if
Replace values in range (function template )
replace_copy
Copy range replacing value (function template )
replace_copy_if
Copy range replacing value (function template )
fill
Fill range with value (function template )
fill_n
Fill sequence with value (function template )
generate
Generate values for range with function (function template )
generate_n
Generate values for sequence with function (function template )
remove
Remove value from range (function template )
remove_if
Remove elements from range (function template )
remove_copy
Copy range removing value (function template )
remove_copy_if
Copy range removing values (function template )
unique
Remove consecutive duplicates in range (function template )
unique_copy
Copy range removing duplicates (function template )
reverse
Reverse range (function template )
reverse_copy
Copy range reversed (function template )
rotate
Rotate left the elements in range (function template )
rotate_copy
Copy range rotated left (function template )
random_shuffle
Randomly rearrange elements in range (function template )
shuffle
Randomly rearrange elements in range using generator (function template ) - copy Copy range of elements (元素复制,在一定范围内 )
- 观察本质
template<class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
while (first!=last) {
*result = *first;
++result; ++first;
}
return result;
}
-----------------------------------------------------------------------------------------------
// copy algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::copy
#include <vector> // std::vector
int main () {
int myints[]={10,20,30,40,50,60,70};
std::vector<int> myvector (7);
std::copy ( myints, myints+7, myvector.begin() );
std::cout << "myvector contains:";
for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}??
--------------------------------------------------------------------------------------
Output:
myvector contains: 10 20 30 40 50 60 70
解释:遍历赋值
看核心代码,?while (first!=last) { *result = *first; ++result; ++first; } 必须有"operator="的支持。
思考:如果OutputIterator result此时没有分配空间,会调用operator=吗?
##最终会调用对象的operator=,那么,outputIterator result一定要分配了空间,会有对象。所以在copy之前,最好用resize()来分配空间,并产生对象:?std::vector<Demo> others; others.resize(demos.size());
???
???????r - copy_n Copy elements (拷贝后面的多少个 )
- 观察本质
template<class InputIterator, class Size, class OutputIterator>
OutputIterator copy_n (InputIterator first, Size n, OutputIterator result)
{
while (n>0) {
*result = *first;
++result; ++first;
--n;
}
return result;
}
-------------------------------------------------------------------------------
??// copy_n algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::copy
#include <vector> // std::vector
int main () {
int myints[]={10,20,30,40,50,60,70};
std::vector<int> myvector;
myvector.resize(7); // allocate space for 7 elements
std::copy_n ( myints, 7, myvector.begin() );
std::cout << "myvector contains:";
for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
----------------------------------------------------------------------------------------------
Output:
myvector contains: 10 20 30 40 50 60 70
解释:
------------------------------------vs2015-----------------------------------
// TEMPLATE FUNCTION copy_n
template<class _InIt,class _Diff,class _OutIt> inline
_OutIt _Copy_n_unchecked2(_InIt _First, _Diff _Count,
_OutIt _Dest, input_iterator_tag)
{ // copy [_First, _First + _Count) to [_Dest, ...), input iterators
if (0 < _Count)
{
*_Dest = *_First;
while (0 < --_Count)
*++_Dest = *++_First;
return (++_Dest);
}
return (_Dest);
}?????
??? - copy_if Copy certain elements of range (有选择性拷贝 )
- 观察本质
template <class InputIterator, class OutputIterator, class UnaryPredicate>
OutputIterator copy_if (InputIterator first, InputIterator last,
OutputIterator result, UnaryPredicate pred)
{
while (first!=last) {
if (pred(*first)) {
*result = *first;
++result;
}
++first;
}
return result;
}
-----------------------------------------------------------------------------------
??// copy_if example
#include <iostream> // std::cout
#include <algorithm> // std::copy_if, std::distance
#include <vector> // std::vector
int main () {
std::vector<int> foo = {25,15,5,-5,-15};
std::vector<int> bar (foo.size());
// copy only positive numbers:
auto it = std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i){return !(i<0);} );
bar.resize(std::distance(bar.begin(),it)); // shrink container to new size
std::cout << "bar contains:";
for (int& x: bar) std::cout << ‘ ‘ << x;
std::cout << ‘\n‘;
return 0;
}
-------------------------------------------------------------------------------------------
Output:
bar contains: 25 15 5
解释:copy_if算法很多应用场景:如在《学生信息管理系统》中查询功能,就能用copy_if简化写法。
-----------------------------------vs2015--------------------------------------------
// TEMPLATE FUNCTION copy_if
template<class _InIt,
class _OutIt,
class _Pr> inline
_OutIt _Copy_if_unchecked(_InIt _First, _InIt _Last, _OutIt _Dest,
_Pr& _Pred)
{ // copy each satisfying _Pred
for (; _First != _Last; ++_First)
if (_Pred(*_First))
{ // validate _Dest and copy
_DEBUG_POINTER(_Dest);
*_Dest++ = *_First;
}
return (_Dest);
}???????
???? - copy_backward Copy range of elements backward (从后面来拷贝 )
- 观察本质
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result )
{
while (last!=first) *(--result) = *(--last);
return result;
}
-----------------------------------------------------------------------------
// copy_backward example
#include <iostream> // std::cout
#include <algorithm> // std::copy_backward
#include <vector> // std::vector
int main () {
std::vector<int> myvector;
// set some values:
for (int i=1; i<=5; i++)
myvector.push_back(i*10); // myvector: 10 20 30 40 50
myvector.resize(myvector.size()+3); // allocate space for 3 more elements
std::copy_backward ( myvector.begin(), myvector.begin()+5, myvector.end() );
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
----------------------------------------------------------------------------------------
??解释:result这里应该是end(),传参时要注意。
核心代码while (last!=first) *(--result) = *(--last); return result;? 拿着result往前copy
------------------------------------vs2015--------------------------------
// TEMPLATE FUNCTION copy_backward
template<class _BidIt1,class _BidIt2> inline
_BidIt2 _Copy_backward_memmove(_BidIt1 _First, _BidIt1 _Last,
_BidIt2 _Dest)
{ // implement copy_backward-like function as memmove
const char * const _First_ch = reinterpret_cast<const char *>(_First);
const char * const _Last_ch = reinterpret_cast<const char *>(_Last);
char * const _Dest_ch = reinterpret_cast<char *>(_Dest);
const size_t _Count = _Last_ch - _First_ch;
return (static_cast<_BidIt2>(
_CSTD memmove(_Dest_ch - _Count, _First_ch, _Count)));
}????
??? - move Move range of elements (元素移动范围 )
- move_backward Move range of elements backward (元素向后移动,在指定范围里)
- swap 有 C++98与C++11两个版本 Exchange values of two objects (两个对象交换值 )
- 观察本质C++98版本
template <class T> void swap ( T& a, T& b )
{
T c(a); a=b; b=c;
}
----------------------------------
??// swap algorithm example (C++98)
#include <iostream> // std::cout
#include <algorithm> // std::swap
#include <vector> // std::vector
int main () {
int x=10, y=20; // x:10 y:20
std::swap(x,y); // x:20 y:10
std::vector<int> foo (4,x), bar (6,y); // foo:4x20 bar:6x10
std::swap(foo,bar); // foo:6x10 bar:4x20
std::cout << "foo contains:";
for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
------------------------------------------------------------------------
??Output:
foo contains: 10 10 10 10 10 10
解释: - 观察本质C++11版本
template <class T> void swap (T& a, T& b)
{
T c(std::move(a)); a=std::move(b); b=std::move(c);
}
template <class T, size_t N> void swap (T (&a)[N], T (&b)[N])
{
for (size_t i = 0; i<N; ++i) swap (a[i],b[i]);
}
------------------------------------------------------------------
// swap algorithm example (C++98)
#include <iostream> // std::cout
#include <algorithm> // std::swap
#include <vector> // std::vector
int main () {
int x=10, y=20; // x:10 y:20
std::swap(x,y); // x:20 y:10
std::vector<int> foo (4,x), bar (6,y); // foo:4x20 bar:6x10
std::swap(foo,bar); // foo:6x10 bar:4x20
std::cout << "foo contains:";
for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
----------------------------------------------------------------------
Output:
foo contains: 10 10 10 10 10 10
解释 : 交换数组
??
------------------------------------------vs2015--------------------------------------
???
???
??? - swap_ranges Exchange values of two ranges (两个范围交换值)
- 观察本质
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2)
{
while (first1!=last1) {
swap (*first1, *first2);
++first1; ++first2;
}
return first2;
}
---------------------------------------------------------------------------------------------
// swap_ranges example
#include <iostream> // std::cout
#include <algorithm> // std::swap_ranges
#include <vector> // std::vector
int main () {
std::vector<int> foo (5,10); // foo: 10 10 10 10 10
std::vector<int> bar (5,33); // bar: 33 33 33 33 33
std::swap_ranges(foo.begin()+1, foo.end()-1, bar.begin());
// print out results of swap:
std::cout << "foo contains:";
for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
std::cout << "bar contains:";
for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
---------------------------------------------------------------------------------
Output:
foo contains: 10 33 33 33 10
bar contains: 10 10 10 33 33
解释:
-------------------------------vs2015--------------------------------------------
// TEMPLATE FUNCTION swap_ranges
template<class _FwdIt1,
class _FwdIt2> inline
_FwdIt2 _Swap_ranges_unchecked(_FwdIt1 _First1, _FwdIt1 _Last1,
_FwdIt2 _Dest)
{ // swap [_First1, _Last1) with [_Dest, ...)
for (; _First1 != _Last1; ++_First1, (void)++_Dest)
_STD iter_swap(_First1, _Dest);
return (_Dest);
}????????????? - 要确保第2区间的长度大于第1区间
- iter_swap Exchange values of objects pointed to by two iterators (由两个迭代器指向的对象进行值的交换 )
- 观察本质
template <class ForwardIterator1, class ForwardIterator2>
void iter_swap (ForwardIterator1 a, ForwardIterator2 b)
{
swap (*a, *b);
}
------------------------------------------------------------------
??// iter_swap example
#include <iostream> // std::cout
#include <algorithm> // std::iter_swap
#include <vector> // std::vector
int main () {
int myints[]={10,20,30,40,50 }; // myints: 10 20 30 40 50
std::vector<int> myvector (4,99); // myvector: 99 99 99 99
std::iter_swap(myints,myvector.begin()); // myints: [99] 20 30 40 50
// myvector: [10] 99 99 99
std::iter_swap(myints+3,myvector.begin()+2); // myints: 99 20 30 [99] 50
// myvector: 10 99 [40] 99
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
----------------------------------------------------------------------------------
?
??Output:
myvector contains: 10 99 40 99
-------------------------------------vs2015------------------------------------------
?// TEMPLATE FUNCTION iter_swap (from <xutility>)
template<class _FwdIt1, class _FwdIt2> inline
void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right)
{ // swap *_Left and *_Right
swap(*_Left, *_Right);
}???? - transform ##理解:增强版本foreach Transform range (进行变换,在指定范围内 )
- 观察本质
template <class InputIterator, class OutputIterator, class UnaryOperator>
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op)
{
while (first1 != last1) {
*result = op(*first1); // or: *result=binary_op(*first1,*first2++);
++result; ++first1;
}
return result;
}
---------------------------------------------------------------------------
// transform algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::transform
#include <vector> // std::vector
#include <functional> // std::plus
int op_increase (int i) { return ++i; }
int main () {
std::vector<int> foo;
std::vector<int> bar;
// set some values:
for (int i=1; i<6; i++)
foo.push_back (i*10); // foo: 10 20 30 40 50
bar.resize(foo.size()); // allocate space
std::transform (foo.begin(), foo.end(), bar.begin(), op_increase);
// bar: 11 21 31 41 51
// std::plus adds together its two arguments:
std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
// foo: 21 41 61 81 101
std::cout << "foo contains:";
for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
-------------------------------------------------------------------------------------
Output:
foo contains: 21 41 61 81 101
------------------------------vs2015------------------------------------
// TEMPLATE FUNCTION transform WITH UNARY OP 一元运算
template<class _InIt,
class _OutIt,
class _Fn1> inline
_OutIt _Transform_unchecked(_InIt _First, _InIt _Last,
_OutIt _Dest, _Fn1& _Func)
{ // transform [_First, _Last) with _Func
for (; _First != _Last; ++_First, (void)++_Dest)
*_Dest = _Func(*_First);
return (_Dest);
}
---------------------------------------
// TEMPLATE FUNCTION transform WITH BINARY OP 二元运算
template<class _InIt1,
class _InIt2,
class _OutIt,
class _Fn2> inline
_OutIt _Transform_unchecked(_InIt1 _First1, _InIt1 _Last1,
_InIt2 _First2, _OutIt _Dest, _Fn2& _Func)
{ // transform [_First1, _Last1) and [_First2, ...) with _Func
for (; _First1 != _Last1; ++_First1, (void)++_First2, ++_Dest)
*_Dest = _Func(*_First1, *_First2);
return (_Dest);
}?????????????? - replace ##理解:增强版的find_if Replace value in range (替换值,在指定容器内 )
- 观察本质
template <class ForwardIterator, class T>
void replace (ForwardIterator first, ForwardIterator last,
const T& old_value, const T& new_value)
{
while (first!=last) {
if (*first == old_value) *first=new_value;
++first;
}
}
------------------------------------------------------------------
// replace algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::replace
#include <vector> // std::vector
int main () {
int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
std::vector<int> myvector (myints, myints+8); // 10 20 30 30 20 10 10 20
std::replace (myvector.begin(), myvector.end(), 20, 99); // 10 99 30 30 99 10 10 99
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
-------------------------------------------------------------
Output:
myvector contains: 10 99 30 30 99 10 10 99
解释:
-----------------------------------vs2015---------------------------------
??
// TEMPLATE FUNCTION replace
template<class _FwdIt,
class _Ty> inline
void _Replace_unchecked(_FwdIt _First, _FwdIt _Last,
const _Ty& _Oldval, const _Ty& _Newval)
{ // replace each matching _Oldval with _Newval
for (; _First != _Last; ++_First)
if (*_First == _Oldval)
*_First = _Newval;
}????????? - replace_if Replace values in range (按条件来替换值,在指定范围内)
- 观察本质
template < class ForwardIterator, class UnaryPredicate, class T >
void replace_if (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred, const T& new_value)
{
while (first!=last) {
if (pred(*first)) *first=new_value;
++first;
}
}
------------------------------------------------------------------------
// replace_if example
#include <iostream> // std::cout
#include <algorithm> // std::replace_if
#include <vector> // std::vector
bool IsOdd (int i) { return ((i%2)==1); }
int main () {
std::vector<int> myvector;
// set some values:
for (int i=1; i<10; i++) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
std::replace_if (myvector.begin(), myvector.end(), IsOdd, 0); // 0 2 0 4 0 6 0 8 0
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
--------------------------------------------------------------------------------
Output:
myvector contains: 0 2 0 4 0 6 0 8 0
解释: 1 需要operator=的支持 2 里面的判断函数必须返回bool值 3 里面的判断函数接收的是一个指针
----------------------------------------------vs2015-----------------------------------------
// TEMPLATE FUNCTION replace_if
template<class _FwdIt,
class _Pr,
class _Ty> inline
void _Replace_if_unchecked(_FwdIt _First, _FwdIt _Last, _Pr& _Pred, const _Ty& _Val)
{ // replace each satisfying _Pred with _Val
for (; _First != _Last; ++_First)
if (_Pred(*_First))
*_First = _Val;
}
??????????
??? - replace_copy ##原序列不变 Copy range replacing value (拷贝替换值 ,在指定范围内)
- 观察本质
template <class InputIterator, class OutputIterator, class T>
OutputIterator replace_copy (InputIterator first, InputIterator last,
OutputIterator result, const T& old_value, const T& new_value)
{
while (first!=last) {
*result = (*first==old_value)? new_value: *first;
++first; ++result;
}
return result;
}
---------------------------------------------------------------------------------
// replace_copy example
#include <iostream> // std::cout
#include <algorithm> // std::replace_copy
#include <vector> // std::vector
int main () {
int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
std::vector<int> myvector (8);
std::replace_copy (myints, myints+8, myvector.begin(), 20, 99);
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
------------------------------------------------------------------------------------------
Output:
myvector contains: 10 99 30 30 99 10 10 99
解释:不改变原序列的值,会产生新的序列来接收
核心代码 while (first!=last) { *result = (*first==old_value)? new_value: *first; ++first; ++result; }?
三目运算赋值,当第1 区间有旧值,则接收新值,否则不变。
??
-------------------------------------vs2015--------------------------------------------------
// TEMPLATE FUNCTION replace_copy
template<class _InIt,class _OutIt,class _Ty> inline
_OutIt _Replace_copy_unchecked(_InIt _First, _InIt _Last,
_OutIt _Dest, const _Ty& _Oldval, const _Ty& _Newval)
{ // copy replacing each matching _Oldval with _Newval 与_newval更换每个匹配_oldval复制
for (; _First != _Last; ++_First, (void)++_Dest)
*_Dest = *_First == _Oldval ? _Newval : *_First;
return (_Dest);
}???????????? - replace_copy_if Copy range replacing value (拷贝替换符合条件的值 ,在指定范围内)
- 观察本质
template <class InputIterator, class OutputIterator, class UnaryPredicate, class T>
OutputIterator replace_copy_if (InputIterator first, InputIterator last,
OutputIterator result, UnaryPredicate pred,
const T& new_value)
{
while (first!=last) {
*result = (pred(*first))? new_value: *first;
++first; ++result;
}
return result;
}
--------------------------------------------------------------------------------------------------
// replace_copy_if example
#include <iostream> // std::cout
#include <algorithm> // std::replace_copy_if
#include <vector> // std::vector
bool IsOdd (int i) { return ((i%2)==1); }
int main () {
std::vector<int> foo,bar;
// set some values:
for (int i=1; i<10; i++) foo.push_back(i); // 1 2 3 4 5 6 7 8 9
bar.resize(foo.size()); // allocate space
std::replace_copy_if (foo.begin(), foo.end(), bar.begin(), IsOdd, 0);
// 0 2 0 4 0 6 0 8 0
std::cout << "bar contains:";
for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
---------------------------------------------------------------------------------
Output:
second contains: 0 2 0 4 0 6 0 8 0
解释:
??核心代码:while (first!=last) { *result = (pred(*first))? new_value: *first; ++first; ++result; }
三目运算赋值,符合条件则赋新,否则保持不变。
-------------------------------vs2015----------------------------------------
// TEMPLATE FUNCTION replace_copy_if
template<class _InIt,
class _OutIt,
class _Pr,
class _Ty> inline
_OutIt _Replace_copy_if_unchecked(_InIt _First, _InIt _Last,
_OutIt _Dest, _Pr& _Pred, const _Ty& _Val)
{ // copy replacing each satisfying _Pred with _Val
for (; _First != _Last; ++_First, (void)++_Dest)
*_Dest = _Pred(*_First) ? _Val : *_First;
return (_Dest);
}
?????????????? - fill Fill range with value (填充值到指定序列 )
- 观察本质
template <class ForwardIterator, class T>
void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
while (first != last) {
*first = val;
++first;
}
}
---------------------------------------------------------------------------------
// fill algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::fill
#include <vector> // std::vector
int main () {
std::vector<int> myvector (8); // myvector: 0 0 0 0 0 0 0 0
std::fill (myvector.begin(),myvector.begin()+4,5); // myvector: 5 5 5 5 0 0 0 0
std::fill (myvector.begin()+3,myvector.end()-2,8); // myvector: 5 5 5 8 8 8 0 0
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
--------------------------------------------------------------------------------------
Output:
myvector contains: 5 5 5 8 8 8 0 0
解释:
核心代码:while (first != last) { *first = val; ++first; }
????
??????---------------------------------------vs2015---------------------------------------
template<class _FwdIt,
class _Ty> inline
void _Fill_unchecked1(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, false_type)
{ // copy _Val through [_First, _Last), no special optimization
for (; _First != _Last; ++_First)
*_First = _Val;
}??? - fill_n Fill sequence with value (按给出的数量,来填充值到容器内)
- 观察本质
template <class OutputIterator, class Size, class T>
OutputIterator fill_n (OutputIterator first, Size n, const T& val)
{
while (n>0) {
*first = val;
++first; --n;
}
return first; // since C++11
}
---------------------------------------------------------------------------------
// fill_n example
#include <iostream> // std::cout
#include <algorithm> // std::fill_n
#include <vector> // std::vector
int main () {
std::vector<int> myvector (8,10); // myvector: 10 10 10 10 10 10 10 10
std::fill_n (myvector.begin(),4,20); // myvector: 20 20 20 20 10 10 10 10
std::fill_n (myvector.begin()+3,3,33); // myvector: 20 20 20 33 33 33 10 10
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
----------------------------------------------------------------------------------------
Output:
myvector contains: 20 20 20 33 33 33 10 10
解释:特别注意空间不够用时,会产生未知错误。
核心代码:while (n>0) { *first = val; ++first; --n; }??? return first; 返回时,first位置已经改变。
-------------------------------vs2015-------------------------------------------
// TEMPLATE FUNCTION fill_n
template<class _OutIt, class _Diff, class _Ty> inline
_OutIt _Fill_n_unchecked1(_OutIt _Dest, _Diff _Count, const _Ty& _Val, false_type)
{ // copy _Val _Count times through [_Dest, ...), no special optimization
for (; 0 < _Count; --_Count, (void)++_Dest)
*_Dest = _Val;
return (_Dest);
}
template<class _OutIt,
class _Diff, class _Ty> inline
? _OutIt _Fill_n_unchecked1(_OutIt _Dest, _Diff _Count, const _Ty& _Val, true_type)
{ // copy _Val _Count times through [_Dest, ...), memset optimization
if (0 < _Count)
{
_CSTD memset(_Dest, _Val, _Count);
return (_Dest + _Count);
}
return (_Dest);
}?????
?? - generate Generate values for range with function (用函数生成有值的序列 )
- 观察本质
template <class ForwardIterator, class Generator>
void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
{
while (first != last) {
*first = gen();
++first;
}
}
------------------------------------------------------------------------------------
// generate algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::generate
#include <vector> // std::vector
#include <ctime> // std::time
#include <cstdlib> // std::rand, std::srand
// function generator:
int RandomNumber () { return (std::rand()%100); }
// class generator:
struct c_unique {
int current;
c_unique() {current=0;}
int operator()() {return ++current;}
} UniqueNumber;
int main () {
std::srand ( unsigned ( std::time(0) ) );
std::vector<int> myvector (8);
std::generate (myvector.begin(), myvector.end(), RandomNumber);
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
std::generate (myvector.begin(), myvector.end(), UniqueNumber);
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
----------------------------------------------------------------------------------
A possible output:
myvector contains: 57 87 76 66 85 54 17 15
myvector contains: 1 2 3 4 5 6 7 8
解释:
??????---------------------------------vs2015-------------------------------------------
?????? - generate_n Generate values for sequence with function (用函数生成多少个有值的序列 )
- 观察本质
template <class OutputIterator, class Size, class Generator>
void generate_n ( OutputIterator first, Size n, Generator gen )
{
while (n>0) {
*first = gen();
++first; --n;
}
}
-----------------------------------------------------------------------
// generate_n example
#include <iostream> // std::cout
#include <algorithm> // std::generate_n
int current = 0;
int UniqueNumber () { return ++current; }
int main () {
int myarray[9];
std::generate_n (myarray, 9, UniqueNumber);
std::cout << "myarray contains:";
for (int i=0; i<9; ++i)
std::cout << ‘ ‘ << myarray[i];
std::cout << ‘\n‘;
return 0;
}
---------------------------------------------------------------------------------
A possible output:
myarray contains: 1 2 3 4 5 6 7 8 9
解释:
核心代码:while (n>0) { *first = gen(); ++first; --n; }?
---------------------------------vs2015-----------------------------
// TEMPLATE FUNCTION generate_n
template<class _OutIt, class _Diff, class _Fn0> inline
_OutIt _Generate_n_unchecked(_OutIt _Dest, _Diff _Count, _Fn0& _Func)
{ // replace [_Dest, _Dest + _Count) with _Func()
for (; 0 < _Count; --_Count, (void)++_Dest)
*_Dest = _Func();
return (_Dest);
}??????
????? - remove ##只移除不做删除,特别注意返回值 Remove value from range (从序列移除值 )
- 观察本质C++98版
template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
ForwardIterator result = first;
while (first!=last) {
if (!(*first == val)) {
*result = *first;
++result;
}
++first;
}
return result;
}
------------------------------------------------------------------------------------------
// remove algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::remove
int main () {
int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20
// bounds of range:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = std::remove (pbegin, pend, 20); // 10 30 30 10 10 ? ? ?
// ^ ^
std::cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
std::cout << ‘ ‘ << *p;
std::cout << ‘\n‘;
return 0;
}
---------------------------------------------------------------------------------------
Output:
range contains: 10 30 30 10 10
解释:注意返回值,返回值是移除后最后的end()??
----------------------------------------vs2015-------------------------------------
// TEMPLATE FUNCTION remove
template<class _FwdIt,
class _Ty> inline
_FwdIt _Remove_unchecked(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
{ // remove each matching _Val
_First = _Find_unchecked(_First, _Last, _Val);
_FwdIt _Next = _First;
if (_First != _Last)
{
for (++_First; _First != _Last; ++_First)
if (!(*_First == _Val))
*_Next++ = _STD move(*_First);
}
return (_Next);
}?????????
????? - 观察本质C++11版
template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
ForwardIterator result = first;
while (first!=last) {
if (!(*first == val)) {
*result = move(*first);
++result;
}
++first;
}
return result;
}
--------------------------------------------------------------------------------------------
// remove algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::remove
int main () {
int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20
// bounds of range:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = std::remove (pbegin, pend, 20); // 10 30 30 10 10 ? ? ?
// ^ ^
std::cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
std::cout << ‘ ‘ << *p;
std::cout << ‘\n‘;
return 0;
}
-------------------------------------------------------------------------------------------
Output:
range contains: 10 30 30 10 10
?
解释 :
核心代码
? ?ForwardIterator result = first;
while (first!=last) {
if (!(*first == val)) {
*result = *first;
++result;
}
++first;
}
------------------------------vs2015-------------------------------------------
// TEMPLATE FUNCTION remove
template<class _FwdIt,
class _Ty> inline
_FwdIt _Remove_unchecked(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
{ // remove each matching _Val
_First = _Find_unchecked(_First, _Last, _Val);
_FwdIt _Next = _First;
if (_First != _Last)
{
for (++_First; _First != _Last; ++_First)
if (!(*_First == _Val))
*_Next++ = _STD move(*_First);
}
return (_Next);
}???????? - remove_if Remove elements from range (从序列移除符合条件的元素 )
- 观察本质
template <class ForwardIterator, class UnaryPredicate>
ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred)
{
ForwardIterator result = first;
while (first!=last) {
if (!pred(*first)) {
*result = *first;
++result;
}
++first;
}
return result;
}
---------------------------------------------------------------------------------
// remove_if example
#include <iostream> // std::cout
#include <algorithm> // std::remove_if
bool IsOdd (int i) { return ((i%2)==1); }
int main () {
int myints[] = {1,2,3,4,5,6,7,8,9}; // 1 2 3 4 5 6 7 8 9
// bounds of range:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = std::remove_if (pbegin, pend, IsOdd); // 2 4 6 8 ? ? ? ? ?
// ^ ^
std::cout << "the range contains:";
for (int* p=pbegin; p!=pend; ++p)
std::cout << ‘ ‘ << *p;
std::cout << ‘\n‘;
return 0;
}
------------------------------------------------------------------------------
Output:
the range contains: 2 4 6 8
?
------------------------vs2015--------------------------------
// TEMPLATE FUNCTION remove_if
template<class _FwdIt,
class _Pr> inline
_FwdIt _Remove_if_unchecked(_FwdIt _First, _FwdIt _Last, _Pr& _Pred)
{ // remove each satisfying _Pred
_First = _Find_if_unchecked(_First, _Last, _Pred);
_FwdIt _Next = _First;
if (_First != _Last)
{
for (++_First; _First != _Last; ++_First)
if (!_Pred(*_First))
*_Next++ = _STD move(*_First);
}
return (_Next);
}???????? - remove_copy Copy range removing value (拷贝序列在新序列中移除值 )
- 观察本质
template <class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy (InputIterator first, InputIterator last,
OutputIterator result, const T& val)
{
while (first!=last) {
if (!(*first == val)) {
*result = *first;
++result;
}
++first;
}
return result;
}
---------------------------------------------------------------------------------
// remove_copy example
#include <iostream> // std::cout
#include <algorithm> // std::remove_copy
#include <vector> // std::vector
int main () {
int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20
std::vector<int> myvector (8);
std::remove_copy (myints,myints+8,myvector.begin(),20); // 10 30 30 10 10 0 0 0
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
----------------------------------------------------------------------------------------
Output:
myvector contains: 10 30 30 10 10 0 0 0
----------------------------------------------vs2015------------------------------------
// TEMPLATE FUNCTION remove_copy
template<class _InIt,
class _OutIt,
class _Ty> inline
_OutIt _Remove_copy_unchecked(_InIt _First, _InIt _Last,
_OutIt _Dest, const _Ty& _Val)
{ // copy omitting each matching _Val
for (; _First != _Last; ++_First)
if (!(*_First == _Val))
{ // validate _Dest and store
_DEBUG_POINTER(_Dest);
*_Dest++ = *_First;
}
return (_Dest);
}
???????????? - remove_copy_if Copy range removing values (拷贝序列并在新序列中移除符合条件的值)
- 观察本质
template <class InputIterator, class OutputIterator, class UnaryPredicate>
OutputIterator remove_copy_if (InputIterator first, InputIterator last,
OutputIterator result, UnaryPredicate pred)
{
while (first!=last) {
if (!pred(*first)) {
*result = *first;
++result;
}
++first;
}
return result;
}
------------------------------------------------------------------------------------
// remove_copy_if example
#include <iostream> // std::cout
#include <algorithm> // std::remove_copy_if
#include <vector> // std::vector
bool IsOdd (int i) { return ((i%2)==1); }
int main () {
int myints[] = {1,2,3,4,5,6,7,8,9};
std::vector<int> myvector (9);
std::remove_copy_if (myints,myints+9,myvector.begin(),IsOdd);
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
-----------------------------------------------------------------------------------------
Output:
myvector contains: 2 4 6 8 0 0 0 0 0
--------------------------------------vs2015--------------------------------------------??????????
// TEMPLATE FUNCTION remove_copy_if
template<class _InIt,
class _OutIt,
class _Pr> inline
_OutIt _Remove_copy_if_unchecked(_InIt _First, _InIt _Last,
_OutIt _Dest, _Pr& _Pred)
{ // copy omitting each element satisfying _Pred
for (; _First != _Last; ++_First)
if (!_Pred(*_First))
{ // validate _Dest and store
_DEBUG_POINTER(_Dest);
*_Dest++ = *_First;
}
return (_Dest);
}?? - unique ##相邻去重复,保留一份 Remove consecutive duplicates in range (删除容器中的连续重复元素 )
- 观察本质
template <class ForwardIterator>
ForwardIterator unique (ForwardIterator first, ForwardIterator last)
{
if (first==last) return last;
ForwardIterator result = first;
while (++first != last)
{
if (!(*result == *first)) // or: if (!pred(*result,*first)) for version (2)
*(++result)=*first;
}
return ++result;
}
--------------------------------------------------------------------------------------
// unique algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::unique, std::distance
#include <vector> // std::vector
bool myfunction (int i, int j) {
return (i==j);
}
int main () {
int myints[] = {10,20,20,20,30,30,20,20,10}; // 10 20 20 20 30 30 20 20 10
std::vector<int> myvector (myints,myints+9);
// using default comparison:
std::vector<int>::iterator it;
it = std::unique (myvector.begin(), myvector.end()); // 10 20 30 20 10 ? ? ? ?
// ^
myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10
// using predicate comparison:
std::unique (myvector.begin(), myvector.end(), myfunction); // (no changes)
// print out content:
std::cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
---------------------------------------------------------------------------------------------------
Output:
myvector contains: 10 20 30 20 10
解释:
???核心代码 while (++first != last)
{ if (!(*result == *first)) // or: if (!pred(*result,*first)) for version (2)
*(++result)=*first;
}
相邻两个值不相等的时候,返回++first
----------------------------------------vs2015--------------------------------------------------
// TEMPLATE FUNCTION unique
template<class _FwdIt> inline
_FwdIt unique(_FwdIt _First, _FwdIt _Last)
{ // remove each matching previous
return (_STD unique(_First, _Last, equal_to<>()));
}
?
// TEMPLATE FUNCTION unique WITH PRED
template<class _FwdIt, class _Pr> inline
_FwdIt _Unique_unchecked(_FwdIt _First, _FwdIt _Last, _Pr& _Pred)
{ // remove each satisfying _Pred with previous
if (_First != _Last)
for (_FwdIt _Firstb; (void)(_Firstb = _First), ++_First != _Last; )
if (_Pred(*_Firstb, *_First))
{ // copy down
for (; ++_First != _Last; )
if (!_Pred(*_Firstb, *_First))
*++_Firstb = _STD move(*_First);
return (++_Firstb);
}
return (_Last);
}??????????????????? - unique_copy Copy range removing duplicates (复制范围删除重复 )
- 观察本质
template <class InputIterator, class OutputIterator>
OutputIterator unique_copy (InputIterator first, InputIterator last,
OutputIterator result)
{
if (first==last) return result;
*result = *first;
while (++first != last) {
typename iterator_traits<InputIterator>::value_type val = *first;
if (!(*result == val)) // or: if (!pred(*result,val)) for version (2)
*(++result)=val;
}
return ++result;
}
-------------------------------------------------------------------------
// unique_copy example
#include <iostream> // std::cout
#include <algorithm> // std::unique_copy, std::sort, std::distance
#include <vector> // std::vector
bool myfunction (int i, int j) {
return (i==j);
}
int main () {
int myints[] = {10,20,20,20,30,30,20,20,10};
std::vector<int> myvector (9); // 0 0 0 0 0 0 0 0 0
// using default comparison:
std::vector<int>::iterator it;
it=std::unique_copy (myints,myints+9,myvector.begin()); // 10 20 30 20 10 0 0 0 0
// ^
std::sort (myvector.begin(),it); // 10 10 20 20 30 0 0 0 0
// ^
// using predicate comparison:
it=std::unique_copy (myvector.begin(), it, myvector.begin(), myfunction);
// 10 20 30 20 30 0 0 0 0
// ^
myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30
// print out content:
std::cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
------------------------------------------------------------------------------
????Output:
myvector contains: 10 20 30
解释:
-------------------------------vs2015-----------------?????
// TEMPLATE FUNCTION unique_copy WITH PRED
template<class _InIt,
class _OutIt,
class _Pr> inline
_OutIt _Unique_copy_unchecked(_InIt _First, _InIt _Last,
_OutIt _Dest, _Pr& _Pred, input_iterator_tag)
{ // copy compressing pairs satisfying _Pred, input iterators
if (_First != _Last)
{
_Iter_value_t<_InIt> _Val = *_First;
for (*_Dest++ = _Val; ++_First != _Last; )
if (!_Pred(_Val, *_First))
{ // copy unmatched
_Val = *_First;
*_Dest++ = _Val;
}
}
return (_Dest);
}
template<class _FwdIt,
class _OutIt,
class _Pr> inline
_OutIt _Unique_copy_unchecked(_FwdIt _First, _FwdIt _Last,
_OutIt _Dest, _Pr& _Pred, forward_iterator_tag)
{ // copy compressing pairs satisfying _Pred, forward iterators
if (_First != _Last)
{
_FwdIt _Firstb = _First;
for (*_Dest++ = *_Firstb; ++_First != _Last; )
if (!_Pred(*_Firstb, *_First))
{ // copy unmatched
_Firstb = _First;
*_Dest++ = *_Firstb;
}
}
return (_Dest);
}? - reverse ##迭代器的类型要支持--操作(双向) Reverse range (逆转序列 )
- 观察本质
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
while ((first!=last)&&(first!=--last)) {
std::iter_swap (first,last);
++first;
}
}
----------------------------------------------------------------------------
// reverse algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::reverse
#include <vector> // std::vector
int main () {
std::vector<int> myvector;
// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
std::reverse(myvector.begin(),myvector.end()); // 9 8 7 6 5 4 3 2 1
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
-------------------------------------------------------------------------------------
Output:
myvector contains: 9 8 7 6 5 4 3 2 1
解释:
核心代码 while ((first!=last)&&(first!=--last)) { std::iter_swap (first,last); ++first; }?
-----------------------------------------------------vs2015--------------------------------
// TEMPLATE FUNCTION reverse
?template<class _BidIt> inline
void _Reverse_unchecked(_BidIt _First, _BidIt _Last)
{ // reverse elements in [_First, _Last), bidirectional iterators
for (; _First != _Last && _First != --_Last; ++_First)
_STD iter_swap(_First, _Last);
}?????????????????? - reverse_copy Copy range reversed (复制序列逆转排列 )
- 观察本质
template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy (BidirectionalIterator first,
BidirectionalIterator last, OutputIterator result)
{
while (first!=last) {
--last;
*result = *last;
++result;
}
return result;
}
--------------------------------------------------------------------------------
// reverse_copy example
#include <iostream> // std::cout
#include <algorithm> // std::reverse_copy
#include <vector> // std::vector
int main () {
int myints[] ={1,2,3,4,5,6,7,8,9};
std::vector<int> myvector;
myvector.resize(9); // allocate space
std::reverse_copy (myints, myints+9, myvector.begin());
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
------------------------------------------------------------------------------------
Output:
myvector contains: 9 8 7 6 5 4 3 2 1
---------------------------vs2015---------------------------------------
// TEMPLATE FUNCTION reverse_copy
template<class _BidIt,
class _OutIt> inline
_OutIt _Reverse_copy_unchecked(_BidIt _First, _BidIt _Last,
_OutIt _Dest)
{ // copy reversing elements in [_First, _Last)
for (; _First != _Last; ++_Dest)
*_Dest = *--_Last;
return (_Dest);
}?????????? - rotate ##以中间元素位置折半旋转序列 Rotate left the elements in range (旋转元素排列 )
- 观察本质
template <class ForwardIterator>
void rotate (ForwardIterator first, ForwardIterator middle,
ForwardIterator last)
{
ForwardIterator next = middle;
while (first!=next)
{
swap (*first++,*next++);
if (next==last) next=middle;
else if (first==middle) middle=next;
}
}
---------------------------------------------------------------------
// rotate algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::rotate
#include <vector> // std::vector
int main () {
std::vector<int> myvector;
// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
std::rotate(myvector.begin(),myvector.begin()+3,myvector.end());
// 4 5 6 7 8 9 1 2 3
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}????
-----------------------------------------------------------------------------
???Output:
myvector contains: 4 5 6 7 8 9 1 2 3
------------------------------------------vs2015----------------------------------
// TEMPLATE FUNCTION rotate
template<class _FwdIt> inline
_FwdIt _Rotate_unchecked1(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last,
forward_iterator_tag)
{ // rotate [_First, _Last), forward iterators
for (_FwdIt _Next = _Mid, _Res = _Last; ; )
{ // swap [_First, ...) into place
_STD iter_swap(_First, _Next);
if (++_First == _Mid)
{ // quit if done, else define next interval
if (++_Next == _Last)
return (_Res == _Last ? _Mid : _Res);
else
_Mid = _Next; // mark end of next interval
}
else if (++_Next == _Last)
{ // wrap to last end
if (_Res == _Last)
_Res = _First;
_Next = _Mid;
}
}
}
???? - rotate_copy Copy range rotated left (左旋转序列)
- 观察本质
template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result)
{
result=std::copy (middle,last,result);
return std::copy (first,middle,result);
}
------------------------------------------------------------------------------
// rotate_copy algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::rotate_copy
#include <vector> // std::vector
int main () {
int myints[] = {10,20,30,40,50,60,70};
std::vector<int> myvector (7);
std::rotate_copy(myints,myints+3,myints+7,myvector.begin());
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
-----------------------------------------------------------------------------------------
Output:
myvector contains: 40 50 60 70 10 20 30
----------------------------vs2015--------------------------------------------------
// TEMPLATE FUNCTION rotate_copy
template<class _FwdIt,
class _OutIt> inline
_OutIt _Rotate_copy_unchecked(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last,
_OutIt _Dest)
{ // copy rotating [_First, _Last)
_Dest = _Copy_unchecked(_Mid, _Last, _Dest);
return (_Copy_unchecked(_First, _Mid, _Dest));
}???????? - random_shuffle Randomly rearrange elements in range (随机重排序列 )
- 观察本质
template <class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,
RandomNumberGenerator& gen)
{
iterator_traits<RandomAccessIterator>::difference_type i, n;
n = (last-first);
for (i=n-1; i>0; --i) {
swap (first[i],first[gen(i+1)]);
}
}
------------------------------------------------------------------------------------
// random_shuffle example
#include <iostream> // std::cout
#include <algorithm> // std::random_shuffle
#include <vector> // std::vector
#include <ctime> // std::time
#include <cstdlib> // std::rand, std::srand
// random generator function:
int myrandom (int i) { return std::rand()%i;}
int main () {
std::srand ( unsigned ( std::time(0) ) );
std::vector<int> myvector;
// set some values:
for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
// using built-in random generator:
std::random_shuffle ( myvector.begin(), myvector.end() );
// using myrandom:
std::random_shuffle ( myvector.begin(), myvector.end(), myrandom);
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ‘ ‘ << *it;
std::cout << ‘\n‘;
return 0;
}
---------------------------------------------------------------------------------------
Possible output:
myvector contains: 3 4 1 6 8 9 2 7 5
-----------------------------------------vs2015-----------------------------------------
// TEMPLATE FUNCTION shuffle WITH URNG
template<class _RanIt,
class _Fn1> inline
void _Random_shuffle_unchecked(_RanIt _First, _RanIt _Last, _Fn1& _Func)
{ // shuffle nonempty [_First, _Last) using random function _Func
if (_Last - _First < 2)
return;
_RanIt _Next = _First;
for (_Iter_diff_t<_RanIt> _Index = 2; ++_Next != _Last; ++_Index)
{ // randomly swap element with self or earlier element
_Iter_diff_t<_RanIt> _Off = _Func(_Index);
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Off < 0 || _Index <= _Off)
{ // report error
_DEBUG_ERROR("random value out of range");
_SCL_SECURE_OUT_OF_RANGE;
}
#elif _ITERATOR_DEBUG_LEVEL == 1
_SCL_SECURE_VALIDATE_RANGE(0 <= _Off && _Off < _Index);
#endif /* _ITERATOR_DEBUG_LEVEL */
_STD iter_swap(_Next, _First + _Off);
}
}???????? - shuffle Randomly rearrange elements in range using generator (使用生成函数随机排列 )
- 观察本质
template <class RandomAccessIterator, class URNG>
void shuffle (RandomAccessIterator first, RandomAccessIterator last, URNG&& g)
{
for (auto i=(last-first)-1; i>0; --i) {
std::uniform_int_distribution<decltype(i)> d(0,i);
swap (first[i], first[d(g)]);
}
}
------------------------------------------------------------------------------------------
// shuffle algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::shuffle
#include <array> // std::array
#include <random> // std::default_random_engine
#include <chrono> // std::chrono::system_clock
int main () {
std::array<int,5> foo {1,2,3,4,5};
// obtain a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
shuffle (foo.begin(), foo.end(), std::default_random_engine(seed));
std::cout << "shuffled elements:";
for (int& x: foo) std::cout << ‘ ‘ << x;
std::cout << ‘\n‘;
return 0;
}
---------------------------------------------------------------------------------------
Possible output:
shuffled elements: 3 1 4 2 5
--------------------------------------vs2015----------------------------------
// TEMPLATE FUNCTION shuffle WITH URNG
template<class _RanIt,
class _Fn1> inline
void _Random_shuffle_unchecked(_RanIt _First, _RanIt _Last, _Fn1& _Func)
{ // shuffle nonempty [_First, _Last) using random function _Func
if (_Last - _First < 2)
return;
_RanIt _Next = _First;
for (_Iter_diff_t<_RanIt> _Index = 2; ++_Next != _Last; ++_Index)
{ // randomly swap element with self or earlier element
_Iter_diff_t<_RanIt> _Off = _Func(_Index);
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Off < 0 || _Index <= _Off)
{ // report error
_DEBUG_ERROR("random value out of range");
_SCL_SECURE_OUT_OF_RANGE;
}
#elif _ITERATOR_DEBUG_LEVEL == 1
_SCL_SECURE_VALIDATE_RANGE(0 <= _Off && _Off < _Index);
#endif /* _ITERATOR_DEBUG_LEVEL */
_STD iter_swap(_Next, _First + _Off);
}
}
???????????? - 小结
- copy 系列与swap要确保输出的空间长度,一定要大于源空间长度。
- copy系列保持了原序列不变,它们都是拷贝了一份到新序列,产生了新序列。copy copy_n copy_if copy_backward
- 交换swap会改变原序列 swap swap_ranges
- 替换replace系列中 replace与replace_if会改变原序列。
- 移除系列中remove与remove_if使用时,一定要注意返回值所表达的意义。返回的是第一个垃圾数据的位置,垃圾数据需要手动删除。
- 移除系列中remove与remove_if在原序列中移除,但不做删除,会有垃圾数据产生。
- 移除系列 remove_copy和remove_copy_if不会产生垃圾数据。它们会保存在一个新的序列。
- 生成函数系列 generate按需求生成 generate_n按条件生成多少个
- 最后就是对已有数据进行加工的系列算法 unique去重 unique_copy去重拷贝 reverse逆转 reverse_copy 逆转并拷贝 rotate折半旋转 rotate_copy旋转并拷贝 random_shuffle随机重排等。
以上是关于STL(14)变动型算法的主要内容,如果未能解决你的问题,请参考以下文章
STL 优先队列的自定义比较函数与 sort() 等泛型算法的自定义比较函数的区别
C++ STL学习 —— 模板泛型算法函数对象lambda 表达式(参数捕获)函数适配器