变易算法
C++ STL的变易算法(Mutating algorithms)是一组能够修改容器元素数据的模板函数,可进行序列数据的复制,变换等。
15、移除复制remove_copy
条件复制,将原容器中不等于某个给定值的元素复制到新容器。
template<class InIt, class OutIt, class T>
OutIt remove_copy(InIt first, InIt last, OutIt x, const T& val);
将迭代器区间[first,last)上不取val值的所有元素复制到迭代器区间[x,x+n),n为实际复制的元素个数。Returns the iterator value that designates the end of the revised sequence.
16、条件移除复制remove_copy_if
是上述函数的一个带谓词判断的版本。
template<class InIt, class OutIt, class Pred>
OutIt remove_copy_if(InIt first, InIt last, OutIt x, Pred pr);
将迭代器区间[first,last)上不满足一元谓词判断条件pr的元素,复制到由迭代器x为起始位置的迭代器区间中。Returns the iterator value that designates the end of the revised sequence.
17、移除remove
将迭代器区间[first,last)上等于val值的所有元素移除掉。
template<class FwdIt, class T>
FwdIt remove(FwdIt first, FwdIt last, const T& val);
将迭代器区间[first,last)上不等于val值的元素,复制到迭代器区间[first,result),其中result是算法函数返回的迭代器,对于[result,last)区间的元素,仍然保持不变。
如v={2,4,3,4,8}中元素全部移除掉,则[first,result)={2,3,8},[result,last)={4,8}.
18、条件移除remove_if
是remove算法的一个带谓词的版本。
template<class FwdIt, class Pred>
FwdIt remove_if(FwdIt first, FwdIt last, Pred pr);
将迭代器区间[first,last)上不满足一元谓词pr判断条件的元素,复制到迭代器区间[first,result),其中result是算法函数返回的迭代器,对于[result,last)区间的元素,仍然保持不变。
19、不连续重复元素复制unique_copy
template<class InIt, class OutIt>
OutIt unique_copy(InIt first, InIt last, OutIt x);
template<class InIt, class OutIt, class Pred>
OutIt unique_copy(InIt first, InIt last, OutIt x, Pred pr);
将迭代器区间[first,last)中邻近相异的元素复制到以x为起始位置的迭代器区间。
如v={2,5,5,5,6,5,2},则操作完后,v1={2,5,6,5,2,0...}
20、剔除连接重复元素unique
template<class FwdIt>
FwdIt unique(FwdIt first, FwdIt last);
将迭代器区间[first,last)中不连续重复的元素或不满足二元谓词判断条件的元素,复制到迭代器区间[first,result),其中result是算法函数返回的迭代器,对于[result,last)区间的元素,仍然保持不变。
template<class FwdIt, class Pred>
FwdIt unique(FwdIt first, FwdIt last, Pred pr);
如v={2,6,6,6,9,6,3},操作完后[first,result)={2,6,9,6,3},[result,last)={6,3},最后v={2,6,9,6,3,6,3}。如下为这个函数的实现过程:
template<typename _ForwardIter>
_ForwardIter unique(_ForwardIter first, _ForwardIter last)
{
first = adjacent_find(first, last);
return unique_copy(first, last, first);
}
21、元素反向reverse
template<class BidIt>
void reverse(BidIt first, BidIt last);
将{a0,a1,a2...an}->{an,...a1,a0}.
22、反向复制reverse_copy
template<class BidIt, class OutIt>
OutIt reverse_copy(BidIt first, BidIt last, OutIt x);
将迭代器区间[first,last)中元素,以反向顺序复制到区间[x,x+(last-first))中。
23、旋转rotate
template<class FwdIt>
void rotate(FwdIt first, FwdIt middle, FwdIt last);
将迭代器区间[first,last)中元素以middle为支点,左旋转[first,middle)元素到[middle,last)元素一侧。假设区间元素为{a0,a1,a2,...ak,...an},ak为middle位置,则旋转后{ak,ak+1,...an,a0,a1,...ak-1}。我们应当意识到,这里旋转并不是像杠杆那样以一个支点旋转,而是类似二叉树的旋转。
template<typename _ForwardIter>
void
rotate(_ForwardIter first,
_ForwardIter middle,
_ForwardIter last,
forward_iterator_tag)
{
if ((first == middle) || (last == middle))
return;
_ForwardIter first2 = middle;
do {
swap(*first++, *first2++);
if (first == middle)
middle = first2;
} while (first2 != last);
first2 = middle;
while (first2 != last) {
swap(*first++, *first2++);
if (first == middle)
middle = first2;
else if (first2 == last)
first2 = middle;
}
}
24、旋转复制rotate_copy
比rotate高效。
template<class FwdIt, class OutIt>
OutIt rotate_copy(FwdIt first, FwdIt middle, FwdIt last, OutIt x);
将迭代器区间[first,last)中元素以middle为旋转支点,将[first,middle)和[middle,last)元素合并并复制到x区间中。假设区间元素为{a0,a1,a2,...ak,...an},ak为middle位置,则旋转后{ak,ak+1,...an,a0,a1,...ak-1}。
template<typename _ForwardIter, typename _OutputIter>
_OutputIter
rotate_copy(_ForwardIter first, _ForwardIter middle,
_ForwardIter last, _OutputIter result)
{
return copy(first, middle, copy(middle, last, result));
}