1. 函数对象
概念:重载函数调用操作符的类的对象。当使用重载()时,也叫仿函数。
本质:函数对象是一个类而不是一个函数。
class add {
public:
add() {
this->count = 0;
}
int operator()(int a, int b) {
count++;
return a + b;
}
int count; //内部状态
};
void show(add& a) {
cout << a.count << endl;
}
int main() {
//1.函数对象使用时可以像普通函数一样调用,可以有参数和返回值。
add p;
cout << p(10, 10) << endl;
//2.函数对象可以有自己的状态。
cout << p.count << endl;
//3.函数对象可以作为参数传递.
show(p);
return 0;
}
2. 谓词
概念:返回bool类型的仿函数称为谓词,如果operator()接收1个参数叫一元谓词,2个叫二元谓词。
二元谓词改变sort的排序规则:
class compare {
public:
bool operator()(int a, int b) {
return a > b;
}
};
void show(vector<int>& v) {
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << (*it) << endl;
}
}
int main() {
srand(time(NULL));
vector<int>v;
for (int i = 0; i < 10; i++) {
v.push_back(rand() % (100 - 20) + 20);
}
sort(v.begin(), v.end(), compare());
show(v);
return 0;
}
3. 内建函数对象
STL内建的一些函数对象,分为算术仿函数,关系仿函数,逻辑仿函数。
感觉没什么用,可以需要的时候直接查。
4. STL常用算法
主要有algorithm,numeric,functional头文件。
4.1 遍历
transform:搬运数据到另一个容器。
for_each:遍历。
class print1 {
public:
void operator()(int a) {
cout << a << endl;
}
};
class Transform {
public:
int operator()(int a) {
return a;
}
};
int main() {
srand(time(NULL));
vector<int>v, v1;
for (int i = 0; i < 10; i++) {
v.push_back(rand() % (100 - 20) + 20);
}
v1.resize(v.size()); //注意目标容器需要申请足够的内存空间存放数据
//transform(源容器开始迭代器,源容器结束迭代器,目标容器开始迭代器,函数/仿函数)
transform(v.begin(), v.end(), v1.begin(), Transform());
//for_each(起始迭代器,结束迭代器,函数/仿函数)
for_each(v1.begin(), v1.end(), print1());
return 0;
}
4.2 查找
find:查找元素,以自定义数据类型为例。
class Person {
public:
Person(char name, int age) {
this->name = name;
this->age = age;
}
//find底层的==号不能判断自定义数据类型,所以要重载
bool operator==(const Person& p) {
if (p.name == this->name && p.age == this->age) {
return true;
}
return false;
}
char name;
int age;
};
void create_person(vector<Person>& v) {
string nameseed = "ABCDEFGHIJK";
for (int i = 0; i < 10; i++) {
Person p(nameseed[i], rand() % (100 - 10) + 10);
v.push_back(p);
}
}
int main() {
srand(time(NULL));
vector<Person>v;
create_person(v);
Person p1(v.back());
vector<Person>::iterator it = find(v.begin(), v.end(), p1);
if (it != v.end()) {
cout << "find it!" << endl;
cout << it->name << " " << it->age << endl;
}
else {
cout << "not found" << endl;
}
return 0;
}
find_if:条件查找。
find_if(v.begin(), v.end(), func/func());
adjacent_find:查找相邻重复元素。找到返回相邻元素第一个位置的迭代器。
adjacent_find(开始迭代器,结束迭代器);
binary_search:二分查找元素是否存在。返回true or false。要求待查找的必须是有序序列。
binary_search(开始迭代器,结束迭代器,查找的元素);
count:统计元素个数。
count(开始迭代器,结束迭代器,待统计的元素);
count_if:按照条件统计元素个数。
count_if(开始迭代器,结束迭代器,func/func());
4.3 排序
sort:
sort(开始迭代器,结束迭代器,谓词(可以不填,默认升序));
//改变为降序最快的写法-内建函数对象
sort(开始迭代器,结束迭代器,greater<int>());
random_shuffle:洗牌,指定范围内元素随机混洗。记得加srand做真随机。
random_shuffle(开始迭代器,结束迭代器);
merge:容器元素合并,存储到另一容器中,要求是两个合并的容器元素必须都是有序且排序规则一致的。
merge(容器1开始迭代器,1结束迭代器,2开始,2结束,合并后的新容器,谓词(不写默认升序));
reverse:反转指定范围的元素
reverse(开始迭代器,结束迭代器);
4.4 拷贝/替换
copy:容器内指定范围的元素拷贝到另一容器。
copy(开始迭代器,结束迭代器,目标容器起始迭代器);
replace:指定范围元素改为新元素。
replace(开始迭代器,结束迭代器,旧元素,新元素);
replace_if:指定范围内满足条件的元素改为新元素。
replace_if(开始迭代器,结束迭代器,谓词,新元素);
swap:互换容器元素,容器需要一致类型。
swap(容器1,容器2);
4.5 算术生成
accumulate:计算容器元素累计和
accumulate(开始迭代器,结束迭代器,起始值);
fill:向容器中填充元素
fill(开始迭代器,结束迭代器,填充值);
4.6 集合算法
set_intersection:求交集。要求两个原set必须是有序序列。
set_intersection(1开始,1结束,2开始,2结束,目标容器开始)
void show(int a){
cout << a << " ";
};
void create(vector<int>& v) {
for (int i = 0; i < 10; i++) {
v.push_back(rand() % (100 - 10) + 10);
}
}
int main() {
srand(time(NULL));
vector<int>s1, s2, s3;
create(s1);
create(s2);
sort(s1.begin(), s1.end());
sort(s2.begin(), s2.end());
s3.resize(min(s1.size(), s2.size())); //交集空间大小最大是较小的集合的大小
for_each(s1.begin(), s1.end(), show);
cout << endl;
for_each(s2.begin(), s2.end(), show);
cout << endl;
vector<int>::iterator itend = set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), s3.begin()); //返回值为交集种最后一个元素对应迭代器
for_each(s3.begin(), itend, show);
return 0;
}
set_union:求并集
set_difference:求差集