STL算法---拷贝/删除/替换算法

23 篇文章 0 订阅
13 篇文章 0 订阅

1. copy / copy_backward(复制序列)


1.1 copy 复制序列

函数原形
template<class InIt, class OutIt> OutIt copy(InIt first, InIt last, OutIt x);

1.2 copy_backward

与copy相同,不过元素是从后面开始顺序拷贝填充
函数原形
template<class BidIt1, class BidIt2> BidIt2 copy_backward(BidIt1 first, BidIt1 last, BidIt2 x);
/
#include "stdafx.h"
#include <algorithm>
#include <numeric>
#include <functional>
#include <vector>
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<int> nV2, nV1;
	std::vector<int>::iterator iter;

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(15);
	nV1.push_back(50);
	nV1.push_back(7);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	nV2.resize(nV1.size() + 1);
	// 调用前nV1: 12, 13, 14, 15, 50, 7, 23, 27, 28, 30, 34, 35, 37
	// 调用前nV2: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
	iter = std::copy(nV1.begin(), nV1.end(), nV2.begin());
	// 调用后nV2: 12, 13, 14, 15, 50, 7, 23, 27, 28, 30, 34, 35, 37, 0(iter)

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(15);
	nV1.push_back(50);
	nV1.push_back(7);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	nV2.clear();
	nV2.resize(nV1.size() + 1);
	// 调用前nV1: 12, 13, 14, 15, 50, 7, 23, 27, 28, 30, 34, 35, 37
	// 调用前nV2: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
	iter = std::copy_backward(nV1.begin(), nV1.end(), nV2.end());	// 注意x是nV2.end()
	// 调用后nV2: 0,12(iter),13,14,15,50,7,23,27,28,30,34,35,37
	return 0;
}
说明:
1. copy 是first->last从左到右顺序遍历, x从左向右前进填充.
2. copy_backward 是last->first从右到左顺序遍历, x从右到左后退填充.

2. iter_swap

交换两个ForwardIterator的值, 就是两个值的交互.
函数原形
template<class FwdIt1, class FwdIt2> void iter_swap(FwdIt1 x, FwdIt2 y);
/
#include "stdafx.h"
#include <algorithm>
#include <numeric>
#include <functional>
#include <vector>
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<int> nV1;

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(15);
	nV1.push_back(50);
	// 调用前: 12, 13, 14, 15, 50
	std::iter_swap(nV1.begin(), nV1.begin() + 2);
	// 调用前: 14, 13, 12, 15, 50

	return 0;
}

3. remove / remove_copy / remove_if / remove_copy_if (删除操作)


3.1 remove

删除[first, last)内所有等于val的全部元素。例如在std::vector中元素被左移.
函数原形
template<class FwdIt, class T> FwdIt remove(FwdIt first, FwdIt last, const T& val);

3.2 remove_copy

将所有不匹配元素复制到一个制定容器,返回OutputIterator指向被拷贝的末元素的下一个位置
函数原形
template<class InIt, class OutIt, class T> OutIt remove_copy(InIt first, InIt last, OutIt x, const T& val);

3.3 remove_if

删除指定范围内输入操作结果为true的所有元素
函数原形
template<class FwdIt, class Pred> FwdIt remove_if(FwdIt first, FwdIt last, Pred pr);

3.4 remove_copy_if

将所有不匹配元素拷贝到一个指定容器
函数原形
template<class InIt, class OutIt, class Pred> OutIt remove_copy_if(InIt first, InIt last, OutIt x, Pred pr);
/
#include "stdafx.h"
#include <algorithm>
#include <numeric>
#include <functional>
#include <vector>
#include <iostream>

class MyObject1
{  
public:
	MyObject1(){}
	~MyObject1(){}
	// 括号操作符
    bool operator()(int val1)  
    {  
        return (0 > val1);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<int> nV2, nV1;
	std::vector<int>::iterator iter;

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(15);
	nV1.push_back(50);
	nV1.push_back(14);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	// 调用前nV1: 12, 13, 14, 15, 50, 14, 23, 27, 28, 30, 34, 35, 37
	iter = std::remove(nV1.begin(), nV1.end(), 14);
	// 调用后nV1: 12, 13, 15, 50, 23, 27, 28, 30, 34, 35, 37, 35(iter), 37
	// 明显最后面两个元素是无效的, remove后元素被左移了, 最后面的35和37只是没有清除.

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(15);
	nV1.push_back(50);
	nV1.push_back(14);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	nV2.resize(nV1.size());
	// 调用前nV1: 12, 13, 14, 15, 50, 14, 23, 27, 28, 30, 34, 35, 37
	iter = std::remove_copy(nV1.begin(), nV1.end(), nV2.begin(), 14);
	// 调用前nV1: 12, 13, 14, 15, 50, 14, 23, 27, 28, 30, 34, 35, 37
	// 调用后nV2: 12, 13, 15, 50, 23, 27, 28, 30, 34, 35, 37, 0(iter), 0

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(-14);
	nV1.push_back(15);
	nV1.push_back(50);
	nV1.push_back(-14);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	// 调用前nV1: 12, 13, -14, 15, 50, -14, 23, 27, 28, 30, 34, 35, 37
	iter = std::remove_if(nV1.begin(), nV1.end(), MyObject1());
	// 调用后nV1: 12, 13, 15, 50, 23, 27, 28, 30, 34, 35, 37, 35(iter), 37
	// 明显最后面两个元素是无效的, remove后元素被左移了, 最后面的35和37只是没有清除.

	return 0;
}

4. replace / replace_copy / replace_if / replace_copy_if (替换操作)

4.1 replace

将指定范围内所有等于vold的元素都用vnew代替
函数原形
template<class FwdIt, class T> void replace(FwdIt first, FwdIt last,const T& vold, const T& vnew);

4.2 replace_copy

与replace类似,不过将结果写入另一个容器
函数原形
template<class InIt, class OutIt, class T> OutIt replace_copy(InIt first, InIt last, OutIt x, const T& vold, const T& vnew);

4.3 replace_if

将指定范围内所有操作结果为true的元素用新值代替
函数原形
template<class FwdIt, class Pred, class T> void replace_if(FwdIt first, FwdIt last, Pred pr, const T& val);

4.4 replace_copy_if

与replace_if,不过将结果写入另一个容器
函数原形
template<class InIt, class OutIt, class Pred, class T> OutIt replace_copy_if(InIt first, InIt last, OutIt x, Pred pr, const T& val);
/
#include "stdafx.h"
#include <algorithm>
#include <numeric>
#include <functional>
#include <vector>
#include <iostream>

class MyObject1
{  
public:
	MyObject1(){}
	~MyObject1(){}
	// 括号操作符
    bool operator()(int val1)  
    {  
        return (0 > val1);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<int> nV2, nV1;
	std::vector<int>::iterator iter;

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(15);
	nV1.push_back(50);
	nV1.push_back(14);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	// 调用前nV1: 12, 13, 14, 15, 50, 14, 23, 27, 28, 30, 34, 35, 37
	std::replace(nV1.begin(), nV1.end(), 14, -14);
	// 调用后nV1: 12, 13, -14, 15, 50, -14, 23, 27, 28, 30, 34, 35, 37

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(15);
	nV1.push_back(50);
	nV1.push_back(14);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	nV2.clear();
	nV2.resize(nV1.size());
	// 调用前nV1: 12, 13, 14, 15, 50, 14, 23, 27, 28, 30, 34, 35, 37
	iter = std::replace_copy(nV1.begin(), nV1.end(), nV2.begin(), 14, -14);
	// 调用前nV1: 12, 13, 14, 15, 50, 14, 23, 27, 28, 30, 34, 35, 37
	// 调用后nV2: 12, 13, -14, 15, 50, -14, 23, 27, 28, 30, 34, 35, 37, end(iter)

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(-14);
	nV1.push_back(15);
	nV1.push_back(50);
	nV1.push_back(-14);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	// 调用前nV1: 12, 13, -14, 15, 50, -14, 23, 27, 28, 30, 34, 35, 37
	std::replace_if(nV1.begin(), nV1.end(), MyObject1(), 14);
	// 调用后nV1: 12, 13, 14, 15, 50, 14, 23, 27, 28, 30, 34, 35, 37, end(iter)

	return 0;
}

5. swap / swap_ranges 

5.1 swap

交换存储在两个对象中的值
函数原形
template<class T> void swap(T& x, T& y);

5.2 swap_ranges

将指定范围内的元素与另一个序列元素值进行交换
函数原形
template<class FwdIt1, class FwdIt2> FwdIt2 swap_ranges(FwdIt1 first, FwdIt1 last, FwdIt2 x);
/
#include "stdafx.h"
#include <algorithm>
#include <numeric>
#include <functional>
#include <vector>
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<int> nV2, nV1;
	std::vector<int>::iterator iter;

	int a = 1;
	int b = 2;
	std::swap(a, b);	// 交还a和b的值

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(50);
	nV1.push_back(14);
	nV1.push_back(15);
	nV2.clear();
	nV2.resize(nV1.size());
	nV2.push_back(26);
	nV2.push_back(18);
	nV2.push_back(27);

	// 调用前nV1: 12, 13, 50, 14, 15
	// 调用前nV2: 0, 0, 0, 0, 0, 26, 18, 27
	std::swap_ranges(nV1.begin(), nV1.end(), nV2.begin());
	// 调用后nV1: 0, 0, 0, 0, 0
	// 调用后nV2: 12, 13, 50, 14, 15, 26, 18, 27

	return 0;
}
说明:
1. swap_ranges中, nV2.size()要大于等于nV1.size()

6. unique / unique_copy (清除序列中重复元素)

6.1 unique

清除序列中连续重复元素。例如: 11, 12, 12, 14 调用后变成 11, 12, 14. 
例如在std::vector中元素被左移.
重载版本使用自定义比较操作
函数原形
template<class FwdIt> FwdIt unique(FwdIt first, FwdIt last);
template<class FwdIt, class Pred> FwdIt unique(FwdIt first, FwdIt last, Pred pr);

6.2 unique_copy

与unique类似,不过把结果输出到另一个容器
函数原形
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);
/
#include "stdafx.h"
#include <algorithm>
#include <numeric>
#include <functional>
#include <vector>
#include <iostream>

class MyObject1
{  
public:
	MyObject1(){}
	~MyObject1(){}
	// 括号操作符
    bool operator()(int val1)  
    {  
        return (0 > val1);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<int> nV2, nV1;
	std::vector<int>::iterator iter;

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(14);
	nV1.push_back(50);
	nV1.push_back(14);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	// 调用前nV1: 12, 13, 14, 14, 50, 14, 23, 27, 28, 30, 34, 35, 37
	iter = std::unique(nV1.begin(), nV1.end());
	// 调用后nV1: 12, 13, 14, 50, 14, 23, 27, 28, 30, 34, 35, 37, 37(iter)
	// 明显最后面的37是无效的, remove后元素被左移了.

	nV1.clear();
	nV1.push_back(12);
	nV1.push_back(13);
	nV1.push_back(14);
	nV1.push_back(14);
	nV1.push_back(50);
	nV1.push_back(14);
	nV1.push_back(23);
	nV1.push_back(27);
	nV1.push_back(28);
	nV1.push_back(30);
	nV1.push_back(34);
	nV1.push_back(35);
	nV1.push_back(37);
	nV2.resize(nV1.size());
	// 调用前nV1: 12, 13, 14, 14, 50, 14, 23, 27, 28, 30, 34, 35, 37
	iter = std::unique_copy(nV1.begin(), nV1.end(), nV2.begin());
	// 调用前nV1: 12, 13, 14, 14, 50, 14, 23, 27, 28, 30, 34, 35, 37
	// 调用后nV2: 12, 13, 14, 50, 14, 23, 27, 28, 30, 34, 35, 37, 0(iter)

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值