stl变易算法(三)
本篇接着前面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变易算法(三)的更多相关文章
- stl变易算法(一)
C++ STL的变易算法是一组可以改动容器元素数据的模板函数,可进行序列容器的复制.交换.替换.填充.移除.旋转等.这些算法对迭代器有较高的要求.详细的迭代器类型随各个算法而定,或向前迭代器.或双向迭 ...
- stl非变易算法(二)
这里接着上篇stl非变易算法(一)进行总结.主要解析算法函数count.count_if.mismatch.equal.search.search_n以及find_end.给出算法函数的实现及測试用例 ...
- 变易算法 - STL算法
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/mutating-algorithms.h ...
- STL非变易算法 - STL算法
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1394600460.html 原创:ST ...
- STL非变易算法
非变易算法:原则上不会变更操作数据的算法. [1] for_each:逐个容器元素,原型for_each(InputIter first, InputIter last, Function f) ...
- 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 ...
- 初探STL之算法
算法 STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包括头文件<algor ...
- [C++ STL] 常用算法总结
1 概述 STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<alg ...
- 常用的STL查找算法
常用的STL查找算法 <effective STL>中有句忠告,尽量用算法替代手写循环:查找少不了循环遍历,在这里总结下常用的STL查找算法: 查找有三种,即点线面: 点就是查找目标为单个 ...
随机推荐
- redis cluster集群理解
Redis Cluster集群 一.redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis 3.0之后版本支持redis-cluster集群,Re ...
- C# linq学习【转】
在说LINQ之前必须先说说几个重要的C#语言特性 一:与LINQ有关的语言特性 1.隐式类型 (1)源起 在隐式类型出现之前, 我们在声明一个变量的时候, 总是要为一个变量指定他的类型 甚至在fore ...
- 安装office1406错误!!!急死个人。。。。。
因为用到Microsoft.Office.Interop.Word,将word转PDF.所以在服务器上需要安装office,但是报错1406,不能将值插入注册表..... 然后百度各种问题,说需要将注 ...
- [ HAOI 2008 ] 玩具取名
\(\\\) \(Description\) 在一个只有\(W,I,N,G\)的字符集中,给出四个字符的若干映射,每个映射为一个字符映射到两个字符,现给你一个假定由一个字符经过多次映射产生的字符串,问 ...
- Leetcode0006--ZigZag Conversion
[转载请注明]https://www.cnblogs.com/igoslly/p/9017638.html 来看一下题目: The string "PAYPALISHIRING" ...
- 04--Spring知识汇总
1. @Autowried注解 Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量.方法及构造函数进行标注,完成自动装配的工作. 通过 @Autowired的使用来消除 se ...
- 在CentOS下搭建Android 开发环境
在CentOS下搭建Android 开发环境 目录 1.环境搭建 1.1.JDK安装 1.2.Eclipse安装 1.3.ADT安装 1.4.Android SDK安装 1.5.Android NDK ...
- Ubuntu Mysql 常用指令
mysql 常用指令及中文乱码解决 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- js常用方法和技巧
随着AJAX的流行,js又得到了很多人的重视,js最大的优势就是它能够对html上的所有元素进行操作,包括创建标签元素,更改元素属性等,这样就使得我们能够利用js来实现很多的动态效果,来提供给用户更强 ...
- 【codeforces 767A】Snacktower
[题目链接]:http://codeforces.com/contest/767/problem/A [题意] 每天掉一个盘子下来;盘子有大小从1..n依次增大n个盘子; 然后让你叠盘子; 最底层为n ...