本篇接着前面stl变易算法(一)stl变易算法(二)继续讲述变易算法。

这里将介绍完余下的变易算法,主要有:填充fill、n次填充fill_n、随机生成元素generate、随机生成n个元素generate_n、移除复制remove_copy、条件移除复制remove_copy_if、移除remove、条件移除remove_if、不连续反复元素复制unique_copy、剔除连续反复元素unique、元素反向reverse、反向复制reverse_copy及旋转rotate 。给出算法实现及实例。


填充fill

fill算法将同一个值填充到容器的一个或多个元素处,使用原型例如以下。将元素区间[first,last)上的元素所有填充为value值。

//fill算法函数的代码
template <class ForwardIterator, class T>
void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
while (first != last) {
*first = val;
++first;
}
}
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << ' ';
} int main(void){
vector<int> v(5);
fill(v.begin(), v.end(), 30);
for_each(v.begin(), v.end(), print);
cout << endl;
return 0;
}

n次填充fill_n

相似于fill算法。fill_n算法可指定填充的元素个数。它的使用原型例如以下。将迭代器区间[first,first+n)个元素的值填充为value新值。

//fill_n函数的代码
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
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << ' ';
} int main(void){
vector<int> v(8);
fill(v.begin(), v.end(), 1);
//前5个元素填充为2
fill_n(v.begin(), 5, 2);
for_each(v.begin(), v.end(), print);
cout << endl;
//所有填充为3
fill_n(v.begin(), v.size(), 3);
for_each(v.begin(), v.end(), print);
cout << endl;
return 0;
}

随机生成元素generate

generate算法为容器生成新元素。使用原型例如以下,将gen发生器生成的一系列元素存入迭代器区间[first,last)的元素区域处。

//generate算法函数代码
template <class ForwardIterator, class Generator>
void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
{
while (first != last) {
*first = gen();
++first;
}
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; //等差数列an+1=an + 3
class sequence{
public:
int a;
sequence(){a=0;}
inline int operator()(){
a=a + 3;
return a;
}
}; void print(int x){
cout << x << endl;
} int main(void){
vector<int> v(10);
sequence an;
generate(v.begin(), v.end(), an);
for_each(v.begin(), v.end(), print);
cout << endl;
return 0;
}

随机生成n个元素generate_n

与generate算法相似,但generate_n算法限定了可填入容器的数值个数。它的使用原型例如以下,将迭代器区间[first,first+n)位置处的n个元素,填入由发生器gen生成的数值。

//generate_n算法函数代码
template <class OutputIterator, class Size, class Generator>
void generate_n ( OutputIterator first, Size n, Generator gen )
{
while (n>0) {
*first = gen();
++first; --n;
}
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream> int main(void){
using namespace std;
vector<int> v(10);
//生成3个伪随机数
generate_n(v.begin(), 3, rand);
for(unsigned int i=0; i<v.size(); i++)
cout << v[i] << ' ';
cout << endl;
return 0;
}

移除复制remove_copy

remove_copy算法实质上是一个条件复制,将容器中不等于某个给定值的元素拷贝到新容器。使用原型例如以下,将迭代器区间[first,last)上不取value的所有元素拷贝到迭代器区间[result,result+n),n为实际复制的元素个数。

//remove_copy函数的代码
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;
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << " ";
} int main(void){
vector<int> v;
v.push_back(2);
v.push_back(4);
v.push_back(3);
v.push_back(4);
v.push_back(8);
//
int iArray[6]={0, 0, 0, 0, 0, 0};
//v不变
remove_copy(v.begin(), v.end(), iArray, 4);
for_each(v.begin(), v.end(), print);
cout << endl;
//打印iArray
for_each(iArray, iArray+6, print);
cout << endl;
return 0;
}

条件移除复制remove_copy_if

remove_copy_if实际上是remove_copy函数的一个带谓词推断的版本号,使用原型例如以下,将迭代器区间[first,last)上不满足谓词推断条件pred的元素,拷贝到有迭代器result为起始位置的迭代器区间中。

//remove_copy_if算法函数的代码
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;
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << " ";
} bool even(int x){ //偶数
return x % 2 ? 0:1;
} int main(void){
//初始化向量v
vector<int> v;
v.push_back(7);
v.push_back(2);
v.push_back(5);
v.push_back(4);
v.push_back(1);
//初始化数组iArray
int iArray[6]={0, 0, 0, 0, 0, 0};
//移除v中偶数,剩余元素拷贝到iArray
remove_copy_if(v.begin(), v.end(), iArray, even);
//打印v,v没有改变
for_each(v.begin(), v.end(), print);
cout << endl;
//打印iArray
for_each(iArray, iArray+6, print);
cout << endl;
return 0;
}

移除remove

remove算法是将容器中等于某个给定值的元素所有除去。

使用原型例如以下,将迭代器区间将迭代器区间[first,last)上不等于value的元素,复制回迭代器区间[first,result),当中result是算法函数返回的迭代器。

迭代器区间[result,last)的元素仍然保持不变。

//remove算法函数的代码
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;
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << " ";
} int main(void){
//初始化向量v
vector<int> v;
v.push_back(2);
v.push_back(4);
v.push_back(3);
v.push_back(4);
v.push_back(8);
//移除4
vector<int>::iterator result=remove(v.begin(), v.end(), 4);
//打印2 3 8
for_each(v.begin(), result, print);
cout << endl;
//打印2 3 8 4 8
for_each(v.begin(), v.end(), print);
cout << endl;
return 0;
}

条件移除remove_if

remove_if是remove函数的一个带谓词推断的版本号,使用原型例如以下,将迭代器区间[first,last)上不满足谓词推断条件pred的元素,复制回迭代器区间[first,result),result是算法返回值。[result,last)上元素保持不变。

//remove_if算法函数的代码
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;
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << " ";
} bool even(int x){ //偶数
return x % 2 ? 0:1;
} int main(void){
//初始化向量v
vector<int> v;
v.push_back(7);
v.push_back(2);
v.push_back(5);
v.push_back(4);
v.push_back(1);
//移除偶数
vector<int>::iterator result=remove_if(v.begin(), v.end(), even);
//打印7 5 1
for_each(v.begin(), result, print);
cout << endl;
//打印7 5 1 4 1
for_each(v.begin(), v.end(), print);
cout << endl;
return 0;
}

不连续反复元素复制unique_copy

unique_copy用于复制不连续的反复元素。它有例如以下两个使用原型,将迭代器区间[first,last)中邻近相异的元素,拷贝到以result为起点的迭代器区间。

//unique_copy算法函数
template <class InputIterator, class OutputIterator>
OutputIterator unique_copy (InputIterator first, InputIterator last,
OutputIterator result); template <class InputIterator, class OutputIterator, class BinaryPredicate>
OutputIterator unique_copy (InputIterator first, InputIterator last,
OutputIterator result, BinaryPredicate pred); 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;
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << ' ';
} int main(void){
vector<int> v;
v.push_back(2);
v.push_back(5);
v.push_back(5);
v.push_back(5);
v.push_back(6);
v.push_back(5);
v.push_back(2);
//
int iArray[6]={0, 0, 0, 0, 0, 0};
//
unique_copy(v.begin(), v.end(), iArray);
//打印2 5 6 5 2 0
for_each(iArray, iArray+6, print);
cout << endl;
return 0;
}

剔除连续反复元素unique

unique算法用于剔除容器中连续反复元素,使用原型例如以下,将迭代器区间[first,last)中不连续反复的元素或不满足谓词推断条件的元素。复制回迭代区间[first,result),result为算法返回值。[result,last)区间的元素。依旧维持不变。

template <class ForwardIterator>
ForwardIterator unique (ForwardIterator first, ForwardIterator last); template <class ForwardIterator, class BinaryPredicate>
ForwardIterator unique (ForwardIterator first, ForwardIterator last,
BinaryPredicate pred); 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;
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << ' ';
} int main(void){
vector<int> v;
v.push_back(2);
v.push_back(6);
v.push_back(6);
v.push_back(6);
v.push_back(9);
v.push_back(6);
v.push_back(3);
//
vector<int>::iterator result=unique(v.begin(), v.end());
//打印2 6 9 6 3
for_each(v.begin(), result, print);
cout << endl;
//打印2 6 9 6 3 6 3
for_each(v.begin(), v.end(), print);
cout << endl;
return 0;
}

元素反向reverse

reverse算法用于容器元素的反向排列,使用原型例如以下,将迭代区间[first,last)的元素反向排列。

template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
while ((first!=last)&&(first!=--last)) {
std::iter_swap (first,last);
++first;
}
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << ' ';
} int main(void){
vector<int> v(10);
for(unsigned int i=0; i<v.size(); i++)
v[i]=i;
for_each(v.begin(), v.end(), print);
cout << endl;
//
reverse(v.begin(), v.end());
for_each(v.begin(), v.end(), print);
cout << endl;
return 0;
}

反向复制reverse_copy

reverse_copy算法用于反向复制容器元素。使用原型例如以下,将迭代器区间[first,last)中的元素,以反向顺序拷贝到迭代器区间[result,result+(last-first))。

template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy (BidirectionalIterator first,
BidirectionalIterator last, OutputIterator result)
{
while (first!=last) {
--last;
*result = *last;
++result;
}
return result;
}
//測试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std; void print(int x){
cout << x << ' ';
} int main(void){
vector<int> v(10);
for(unsigned int i=0; i<v.size(); i++)
v[i]=i;
//
int iArray[10]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
//
reverse_copy(v.begin(), v.end(), iArray);
for_each(iArray, iArray+10, print);
cout << endl;
return 0;
}

旋转rotate

rotate算法用于旋转某个迭代器区间的元素。使用原型例如以下。将迭代器区间[first,last)中元素以middle为支点。左旋转[first,middle)元素到[middle,last)的一側。

//rotate算法函数的代码
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;
}
}
//測试用例
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; int main () {
vector<int> myvector; for (int i=1; i<10; ++i)
myvector.push_back(i); // 1 2 3 4 5 6 7 8 9 rotate(myvector.begin(),myvector.begin()+3,myvector.end());
// 4 5 6 7 8 9 1 2 3
for (vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
cout << ' ' << *it;
cout << '\n';
return 0;
}

完结。

转载请注明出处:http://blog.csdn.net/lsh_2013/article/details/46894197

stl变易算法(三)的更多相关文章

  1. stl变易算法(一)

    C++ STL的变易算法是一组可以改动容器元素数据的模板函数,可进行序列容器的复制.交换.替换.填充.移除.旋转等.这些算法对迭代器有较高的要求.详细的迭代器类型随各个算法而定,或向前迭代器.或双向迭 ...

  2. stl非变易算法(二)

    这里接着上篇stl非变易算法(一)进行总结.主要解析算法函数count.count_if.mismatch.equal.search.search_n以及find_end.给出算法函数的实现及測试用例 ...

  3. 变易算法 - STL算法

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/mutating-algorithms.h ...

  4. STL非变易算法 - STL算法

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1394600460.html 原创:ST ...

  5. STL非变易算法

    非变易算法:原则上不会变更操作数据的算法. [1]    for_each:逐个容器元素,原型for_each(InputIter first, InputIter last, Function f) ...

  6. STL所有算法简介 (转) http://www.cnblogs.com/yuehui/archive/2012/06/19/2554300.html

    STL所有算法简介 STL中的所有算法(70个) 参考自:http://www.cppblog.com/mzty/archive/2007/03/14/19819.htmlhttp://hi.baid ...

  7. 初探STL之算法

    算法 STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包括头文件<algor ...

  8. [C++ STL] 常用算法总结

    1 概述 STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<alg ...

  9. 常用的STL查找算法

    常用的STL查找算法 <effective STL>中有句忠告,尽量用算法替代手写循环:查找少不了循环遍历,在这里总结下常用的STL查找算法: 查找有三种,即点线面: 点就是查找目标为单个 ...

随机推荐

  1. ACM_出题人这样不好吧

    出题人这样不好吧 Time Limit: 2000/1000ms (Java/Others) Problem Description: 作为编协的第一次月赛,肯定是要有防AK(ALL KILL)的题目 ...

  2. [转]linux下logrotate 配置和理解

    转自:http://blog.csdn.net/cjwid/article/details/1690101 对于Linux 的系统安全来说,日志文件是极其重要的工具.系统管理员可以使用logrotat ...

  3. 【转】Linux账号管理之useradd

    转自:http://www.jb51.net/article/45848.htm Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然 ...

  4. Data URI scheme:data:image/jpeg;

    今天在用一个croppic的jQuery裁剪图片的插件的时候,发现在后台获取图片时,无法通过Request.File获取了,但是通过Request.Form[]可以.用firebug跟了一下发现,图片 ...

  5. JVM 优化之逃逸分析

    整理自 周志明<深入JVM> 1, 是JVM优化技术,它不是直接优化手段,而是为其它优化手段提供依据. 2,逃逸分析主要就是分析对象的动态作用域. 3,逃逸有两种:方法逃逸和线程逃逸.   ...

  6. jQuery——尺寸位置

    获取宽:$(".box").width() 设置宽:$(".box").width(200) 获取高:$(".box").height() ...

  7. JS——滚动条

    1.核心思想与之前的拖拽盒子是一样的 2.完全将鼠标在盒子中的坐标给滚动条是错的,因为这样会使滚动条顶部立刻瞬间移动到鼠标位置 3.必须在鼠标按下事件时记住鼠标在滚动条内部的坐标,再将鼠标在盒子中的坐 ...

  8. html——a标签中target属性

    有 4 个保留的目标名称用作特殊的文档重定向操作: _blank 浏览器总在一个新打开.未命名的窗口中载入目标文档. _self 这个目标的值对所有没有指定目标的 <a> 标签是默认目标, ...

  9. [Windows Server 2008] 安装IIS7.5及FTP

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装IISII ...

  10. 扩增子图表解读4曼哈顿图:差异分类级别Taxonomy

    曼哈顿图 Manhattan Plot 曼哈顿图本质上是一个散点图,用于显示大量非零大范围波动数值,最早应用于全基因组关联分析(GWAS)研究展示高度相关位点.它得名源于样式与曼哈顿天际线相似(如下图 ...