算法 | 功能 |
---|---|
copy | 将一个范围中的元素拷贝到新的地方,并返回目的位置的尾迭代器。 |
copy_backward | 从后往前复制。 |
fill | 用指定值填充范围。 |
fill_n | 用n个指定值填充。 |
generate | 用一个函数的执行结果 填充指定范围 。 |
generate_n | 用一个函数的n次执行结果 填充指定范围。 |
iter_swap | 交换迭代器指向的元素。 |
move | 获得右值引用。 |
remove/replace | 移除/替换 等于给定值的元素。 |
unique | 对于范围内的连续等值元素 只保留一份。 |
shuffle | 打乱指定范围内的元素顺序。 |
函数原型:
template <class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);
从前往后 复制。
返回值:返回最后一个被复制的元素的迭代器 + 1。
整个copy过程将调用 assignment operator。
函数等价于:
template
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
while (first!=last) {
*result = *first; // *first 复制到 *result 处。
++result; ++first; // *result 已初始化, 所以调用的将是 赋值运算符。
}
return result;
}
需要注意的事项:
有解引用操作的迭代器需要保证在 begin() + size() - 1 范围内。否则,越界访问,将触发assert。
例如:
vector<int> iv(3); //调用int的“默认构造函数”初始化iv, 而且 iv.size() == 3
auto it = iv.end();
int val = *it ; // 这个很明显,此时的it相当于下标3,动态数组 iv[3] 越界。
auto it2 = iv.begin() + 3;
int val2 = *it2; // 同理,这个也造成越界
当出现越界访问时,将触发以下断言(assert):
vector iterator + offset out of range
复制的目的地需要已经初始化。也就是在调用copy的过程中,不会调用对象的构造函数。 这也是与 uninitialized_copy 的主要区别。
copy 是依次调用重载的运算符=,uninitialized_copy 是依次调用拷贝构造函数。如果目标区间是未初始化的,应该用uninitialized_copy, 否则用copy。
函数原型:
template <class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward (BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result);
从后往前复制。
跟 copy 相比,以相反的方向进行copy操作。
copy 过程同样将调用 assignment operator。
函数等价于:
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result )
{
while (last!=first)
*(--result) = *(--last);
return result;
}
示例 1
#include // std::cout
#include // std::copy_backward
#include // 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; // 10 20 30 10 20 30 40 50
std::cout << '\n';
return 0;
}
函数原型:
template <class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& val);
用 val 填充范围 [ first,last )。
函数等价于:
template <class ForwardIterator, class T>
void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
while (first != last) {
*first = val;
++first;
}
}
函数原型:
template <class OutputIterator, class Size, class T>
void fill_n (OutputIterator first, Size n, const T& val);
函数原型:
template <class ForwardIterator, class Generator>
void generate (ForwardIterator first,
ForwardIterator last, Generator gen);
将一个函数的执行结果保存到指定范围之中。函数执行次数是 last - first 次。
函数等价于:
template <class ForwardIterator, class Generator>
void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
{
while (first != last) {
*first = gen();
++first;
}
}
函数原型:
template <class OutputIterator, class Size, class Generator>
void generate_n (OutputIterator first, Size n, Generator gen);
示例2 :
#include // std::cout
#include // 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;
}
函数原型:
template <class ForwardIterator1,class ForwardIterator2>
void iter_swap (ForwardIterator1 a,ForwardIterator2 b);
函数等价于:
template <class ForwardIterator1, class ForwardIterator2>
void iter_swap (ForwardIterator1 a, ForwardIterator2 b)
{
swap (*a, *b);
}
函数原型:
template <class T>
typename remove_reference<T>::type&& move (T&& arg) noexcept;
获得左值和临时变量 的右值引用。
函数等价于:
static_castdecltype(arg)>::type&&>(arg);
示例3 :
#include // std::move
#include // std::cout
#include // std::vector
#include // std::string
int main () {
std::string foo = "foo-string";
std::string bar = "bar-string";
std::vector<std::string> myvector;
myvector.push_back (foo); // copies
myvector.push_back (std::move(bar)); // moves
std::cout << "myvector contains:";
for (std::string& x:myvector) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
函数原型:
template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first,ForwardIterator last, const T& val);
template <class ForwardIterator, class T>
void replace (ForwardIterator first,ForwardIterator last,const T& old_value, const T& new_value);
函数原型:
template <class ForwardIterator>
ForwardIterator unique (ForwardIterator first,ForwardIterator last);
template <class ForwardIterator,
class BinaryPredicate>
ForwardIterator unique (ForwardIterator first,ForwardIterator last,BinaryPredicate pred);
对于范围内的连续等值元素 只保留一份。
函数等价于:
template
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;
}
示例4 :
#include // std::cout
#include // std::unique, std::distance
#include // 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;
}
函数原型:
template <class RandomAccessIterator, class URNG>
void shuffle (RandomAccessIterator first,
RandomAccessIterator last, URNG&& g);
使用指定的随机数引擎打乱指定范围内的元素位置。
函数等价于:
template<class _RanIt,
class _Fn1,
class _Diff> inline
void _Random_shuffle(_RanIt _First, _RanIt _Last, _Fn1& _Func, _Diff *)
{ // shuffle nonempty [_First, _Last) using random function _Func
_RanIt _Next = _First;
for (_Diff _Index = 2; ++_Next != _Last; ++_Index)
{ // randomly swap element with self or earlier element
_Diff _Off = _Func(_Index);
_STD iter_swap(_Next, _First + _Off);
}
}
示例5 :
#include // std::cout
#include // std::shuffle
#include // std::array
#include // std::default_random_engine
#include // 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;
}