本篇接着前面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. [转]Linux 正则表达式详解

    转自:http://www.jb51.net/article/42989.htm 一.linux文本查找命令 在说linux正规表达式之前,还介绍下linux中查找文本文件常用的三个命令: 1.gre ...

  2. Laravel5.1学习笔记17 数据库3 数据迁移

    介绍 建立迁移文件 迁移文件结构 执行迁移 回滚迁移 填写迁移文件  创建表 重命名/ 删除表 创建字段 修改字段 删除字段 建立索引 删除索引 外键约束 #介绍 Migrations are lik ...

  3. unity3d 各键值对应代码

    KeyCode :KeyCode是由Event.keyCode返回的.这些直接映射到键盘上的物理键.  值        对应键 Backspace     退格键 Delete      Delet ...

  4. C# 窗体 切换、重复显示等遗留问题解决(第五天)

    一.解决同一窗体多次点击重复显示BUG (1)点击弹出学校窗体 #region 弹出学校窗体 /// <summary> /// 弹出学校窗体 /// </summary> / ...

  5. Sping bean的作用域

    单例(Singleton):在整个应用中,只创建bean的一个实例.(默认) 原型(Prototype):每次注入或者通过Sping应用上下文获取的时候,都会创建一个新的bean. 回话(Sessio ...

  6. 如何使用 Python 创建一名可操控的角色玩家

    在 这个系列的第一篇文章 中,我解释了如何使用 Python 创建一个简单的基于文本的骰子游戏.在第二部分中,我向你们展示了如何从头开始构建游戏,即从 创建游戏的环境 开始.但是每个游戏都需要一名玩家 ...

  7. 北京Python开发培训怎么选?

    北京的地理优势和经济优势基本无需多言,作为全国机会最多的地方,吸引了无数的北漂前赴后继.作为中国互联网中心之一,北京有海量Python岗位正在等待大家淘金. 近几年中,Python一直是市场上最受欢迎 ...

  8. C# 泛基

    1 你有时候希望在父类规定一些行为,让子类无法修改,但是这些实现是依赖一个子类才能获取的值,你又不可能知道所有的子类 ,没办法替它在父类里面初始化,这时候就需要在父类里面定义一个每个子类一个的,但又是 ...

  9. IO编程——复制一个文件中的内容到另一个文件

    public class TestIO { public static void main(String[] args) { File inputFile = new File("a.txt ...

  10. H5 应用程序缓存(离线缓存)

    离线缓存这个功能的实现有以下步骤: 1,以nginx做web服务器为例,在mime.types文件中添加一行:text/cache-manifest     manifest,作用是为了让服务器识别该 ...