C++提高之STL(三)

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:求差集

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值