transform
作用:
搬运容器到另一个容器
语法
transform(源容器起始迭代器,源容器结束迭代器,目标开始迭代器,函数或函数对象)
//仿函数
class Transform {
public:
int operator()(int v) {
return v;
}
};
void test23() {
vector<int>v;
for(int i=0;i<10;i++){
v.push_back(i);
}
vector<int>vtarget; //目标容器
transform(v.begin(), v.end(), vtarget.begin(), Transform());
for_each (vtarget.begin(), vtarget.end(), MyPrint());
}
注意:
以上代码会报错
报错原因是因为在创建目标容器的时候没有指定内存大小,所以当将源容器中的数据搬过去时没有足够的内存存放
正确代码
vector<int>vtarget; //目标容器
vtarget.resize(v.size()); //给定内存大小
## find
find(_InIt _First, const _InIt _Last, const _Ty& _Val)
- 第一个参数为迭代器的起始位置,第二个参数为迭代器的结束位置,第三个参数是要查找的值
- 返回找到的第一个匹配值的位置
- 返回值的类型是一个迭代器,所以要声明一个迭代器接受
- 如果没找到返回迭代器最后的位置end()
查找大于5的数值
void test() {
vector<int>v;
forpush(v); //forpush 是我自定义的一个向容器插入10个数的函数
vector<int>::iterator it = find(v.begin(), v.end(), 5);
it == v.end() ? cout << "未找到" << endl : cout << "等于5的找到了"<<endl;
it == v.end() ? cout << "未找到" << endl : cout << "大于5的找到了" <<*it<<endl;
}
查找自定义数据类型
创建一个person类
创建几个person类对象并将他们放入容器中
void test() {
vector<person>v;
person p1("a", 10);
person p2("b", 20);
person p3("c", 30);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
vector<person>::iterator it = find(v.begin(), v.end(), p2);
if (it != v.end()) { cout << "找到了" << endl; }
}
运行结果报错
为什么呢?
编译器不认识p2是个什么东西,所以无法比较容器中的值跟要查找的值是不是同一个东西,所以我们要通过重载==运算符来告诉它应该怎么对比
在person类中重载运算符
class person {
public:
person(string name, int age) {
this->m_age = age;
this->m_name=name;
}
bool operator==(const person& p) { //需要重载==运算符
if (this->m_name == p.m_name && this->m_age == p.m_age) {
return true;
}else
return false;
}
int m_age;
string m_name;
};
就能正确执行了
binary_search 二分查找法
作用:查找指定元素是否存在
注意
必须在有序序列中使用
语法:
bool binary_search(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
返回一个bool类型的值
void test27() {
vector<int>v;
forpush(v);
bool ret = binary_search(v.begin(), v.end(), 1);
cout << ret << endl;
}
random_shuffle 洗牌算法
概念:顾名思义就是把牌洗乱,也就是打乱数容器中的数值的排列
void random_shuffle(_RanIt _First, _RanIt _Last) { // shuffle [_First, _Last) using rand()
语法:输入一个迭代器的区间
将区间内的数值顺序打乱
void test28() {
//随机种子
srand((unsigned int)time(NULL));
vector<int>v;
for (int i = 0; i < 10; i++) {
v.push_back(i);
}
random_shuffle(v.begin(),v.end());
for_each(v.begin(), v.end(), MyPrint());
}
merge 合并容器
merge(a.begin(),a.end(),b.begin(),b.end(),目标容器.begin())
- 合并两个容器并存储到另一个容器中
- 两个容器必须是有序的
定义两个容器并给定几个值
vector<int>v;
vector<int>v2;
for (int i = 0; i < 10; i++) {
v.push_back(i);
}
for (int i = 10; i < 20; i++) {
v2.push_back(i);
创建一个用于存放合并后容器的目标容器
vector<int>vTarget;
vTarget.resize(v.size() + v2.size()); //得先给容器分配大小
注意
创建目标容器时候可用resize给定容器大小,否则将会报错
合并容器并遍历
merge(v.begin(), v.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), vTarget.end(), MyPrint());
}
accumulate
作用
对顺序表元素累计求和
语法
accumulate(start,end,initialvalue)
其中start指向首元素,end 指向尾元素的下一个位置。因此要累计求和的元素范围是[start,end)
实现
STL的算法accumulate利用操作符++,从start开始,到end结束,相继访问要累计求和的顺序表元素。因此,对于任意- -个序列,如果它的元素可以通过重复应用操作符++来访
问,那么就可以用这个算法对它的值累计求和。一维数组和sTL容器vector都是这种顺序表实例。
另一个更通用的形式
语法 accumulate(start,end,initiavalue,operator)
其中operator是一个函数,它规定了在累计过程中的操作.
列如,利用stl的函数对象multiolies能狗计算数组元素的乘积
template<class T>
T product(T a[],int n){//返回数组a[0:n-1]的累计和
T theproduct=1;
return accumulate(a,a+n,theproduct,mutiplies<t>());
}