STL常用算法【内置类型和自定义类型的实现】

自定义数据类型如下:
Cat类

class Cat {
public:
	Cat(string name,int age) {
		this->cat_name = name;
		this->cat_age = age;
	}
	bool operator==(const Cat &c) {//重载==运算符,后边自定义数据类型时作比较用
		if (this->cat_age == c.cat_age && this->cat_name == c.cat_name) {
			return true;
		}
		else return false;
	}
	string cat_name;
	int cat_age;
};

遍历算法

使用时要包含头文件#include<algorithm>,话不多说直接上代码,在注释中会表明要点以及使用细则

void printInt(int val) { //用于for_each中填入的函数
	cout << val << endl;
}

class printCat {//用于for_each中填入的仿函数
public:
	void operator()(const Cat c)  {
		cout << "小猫的名字:" << c.cat_name << "小猫的年龄:" << c.cat_age << endl;
	}
};

int transformAdd100(int val) { //用于transform中填入的函数
	 return val + 100;
}

class tranformAddCatAge100 {//用于transform中填入的仿函数
public:
	Cat operator()(const Cat c) {
		Cat c1(c.cat_name, c.cat_age + 100);
		return c1;
	}
};

void test_for() {
	vector<int> int_vector;
	int_vector.emplace_back(1);
	int_vector.emplace_back(2);
	int_vector.emplace_back(3);
	Cat c1("aa", 12);
	Cat c2("bb", 13);
	Cat c3("cc", 14);
	vector<Cat> cat_vector;
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c2);
	cat_vector.emplace_back(c3);
	
	//第一种遍历方式,auto是自动推断数据类型。
	for (auto a : int_vector) { 
		cout << a << " ";
	}
	for (auto a : cat_vector) {
		cout << "小猫的名字:" << a.cat_name << "小猫的年龄:" << a.cat_age << endl;
	}

	//第二种遍历方式,利用for_each来遍历,前边两个参数是迭代器,后边的参数是执行的函数,也可以是仿函数
	for_each(int_vector.begin(), int_vector.end(), printInt);
	for_each(cat_vector.begin(), cat_vector.end(), printCat());

	//第三种transform搬运函数,要先申请空间,第三个参数是搬运的目标容器的起始位置。
	vector<int> int_vector1;
	int_vector1.resize(int_vector.size());
	transform(int_vector.begin(), int_vector.end(), int_vector1.begin(), transformAdd100);
	for_each(int_vector1.begin(), int_vector1.end(), printInt);

	vector<Cat> cat_vector1;
	cat_vector1.resize(cat_vector.size(),c1);//resize还有一个重载的版本,申请空间以后后边要加上单位空间的大小,默认的有一个初始值,
											//但是我们如果自定义类就要自己设定初始值,就是类的一个大小。				
	transform(cat_vector.begin(), cat_vector.end(), cat_vector1.begin(), tranformAddCatAge100());
	for_each(cat_vector1.begin(), cat_vector1.end(), printCat());
}

查找算法

#include<algorithm>包含头文件,实现步骤也包括内置类型和自定义数据类型。

class findGreatOne {
public:
	bool operator()(int val) {
		return val > 1;
	}
};

class findCatAgeGreatTen {
public:
	bool operator()(const Cat c) {
		return c.cat_age > 10;
	}
};

void test_lookup() {
	vector<int> int_vector;
	int_vector.emplace_back(1);
	int_vector.emplace_back(1);
	int_vector.emplace_back(2);
	int_vector.emplace_back(2);
	int_vector.emplace_back(3);
	Cat c1("aa", 12);
	Cat c2("bb", 13);
	Cat c3("cc", 14);
	vector<Cat> cat_vector;
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c2);
	cat_vector.emplace_back(c2);
	cat_vector.emplace_back(c3);

	//find函数
	vector<int>::iterator it_int = find(int_vector.begin(), int_vector.end(), 1);
	if (it_int != int_vector.end()) {
		cout << "找到了!" << *it_int << endl;
	}
	else {
		cout << "不存在 1 这个数!" << endl;
	}

	Cat c4("aa", 12);
	vector<Cat>::iterator it_cat = find(cat_vector.begin(), cat_vector.end(), c4);
	if (it_cat != cat_vector.end()) {
		cout << "找到了:姓名 " << it_cat->cat_name << " 年龄: " << it_cat->cat_age << endl;
	}
	else {
		cout << "没找到" << endl;
	}

	//find_if函数 第三个参数是谓词,对比条件,谓词在上一篇文章中有介绍。
	it_int = find_if(int_vector.begin(), int_vector.end(), findGreatOne());
	if (it_int != int_vector.end()) {
		cout << "找到了!" << *it_int << endl;
	}
	else {
		cout << "不存在大于 1 的数!" << endl;
	}

	it_cat = find_if(cat_vector.begin(), cat_vector.end(), findCatAgeGreatTen());
	if (it_cat != cat_vector.end()) {
		cout << "找到了:姓名 " << it_cat->cat_name << " 年龄: " << it_cat->cat_age << endl;
	}
	else {
		cout << "没找到猫的年龄大于10的数据~" << endl;
	}

	//adjacent_find 查找相邻重复元素,找到返回相邻元素的第一个位置,
	it_int = adjacent_find(int_vector.begin(), int_vector.end());
	if (it_int != int_vector.end()) {
		cout << "找到了!" << *it_int << endl;
	}
	else {
		cout << "不存在相邻且相等的数!" << endl;
	}

	it_cat = adjacent_find(cat_vector.begin(), cat_vector.end());
	if (it_cat != cat_vector.end()) {
		cout << "找到了:姓名 " << it_cat->cat_name << " 年龄: " << it_cat->cat_age << endl;
	}
	else {
		cout << "没找到相邻且相等的数据~" << endl;
	}

	//binary_search 二分查找,返回值是布尔类型。容器中元素必须是有序的。
	if (binary_search(int_vector.begin(), int_vector.end(), 2)) {
		cout << "找到了2" << endl;
	}
	else {
		cout << "没有找到2" << endl;
	}
	
	//count函数 统计一个元素出现的个数,在自定义类型中,要重载==运算符
	int num = count(int_vector.begin(), int_vector.end(), 1);
	cout << " 1 出现了 " << num << " 次" << endl;

	Cat c5("aa", 12);
	num = count(cat_vector.begin(), cat_vector.end(), c5);
	cout << "姓名:" << c5.cat_name << " 年龄:" << c5.cat_age << " 出现了 " << num << " 次。" << endl;

	//count_if,按条件查找,这里的条件是谓词
	num = count_if(int_vector.begin(), int_vector.end(), findGreatOne());
	cout << "大于1的数总共有 " << num << " 个" << endl;

	num = count_if(cat_vector.begin(), cat_vector.end(), findCatAgeGreatTen());
	cout << "年龄大于10的小猫总共有 " << num << " 只" << endl;
}

排序算法

排序算法中,凡是不支持随机访问的容器都有自己的一套排序算法。

class sortForCatAge_Down {//二元谓词实现按小猫年龄降序排列
public:
	bool operator()(const Cat c1,const Cat c2) {
		return c1.cat_age > c2.cat_age;
	}
};
void printInt(int val) { //用于for_each中填入的函数
	cout << val << endl;
}

class printCat {//用于for_each中填入的仿函数
public:
	void operator()(const Cat c)  {
		cout << "小猫的名字:" << c.cat_name << "小猫的年龄:" << c.cat_age << endl;
	}
};
void test_sort() {
	vector<int> int_vector;
	int_vector.emplace_back(6);
	int_vector.emplace_back(5);
	int_vector.emplace_back(4);
	int_vector.emplace_back(3);
	int_vector.emplace_back(2);
	Cat c1("aa", 12);
	Cat c2("bb", 16);
	Cat c3("cc", 14);
	Cat c4("dd", 2);
	vector<Cat> cat_vector;
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c4);
	cat_vector.emplace_back(c2);
	cat_vector.emplace_back(c3);

	//sort默认的是升序,现在用一个谓词来实现降序排列。
	cout << "************** sort ****************" << endl;
	sort(int_vector.begin(), int_vector.end(), greater<int>());//要包含头文件 #include<functional>
	for_each(int_vector.begin(), int_vector.end(), printInt);
	cout << endl;

	sort(cat_vector.begin(), cat_vector.end(), sortForCatAge_Down());
	for_each(cat_vector.begin(), cat_vector.end(), printCat());

	//revers实现反转,内置数据类型和自定义数据类型都可以直接用
	cout << "************** revers ****************" << endl;
	reverse(int_vector.begin(), int_vector.end());
	for_each(int_vector.begin(), int_vector.end(), printInt);
	cout << endl;

	reverse(cat_vector.begin(), cat_vector.end());
	for_each(cat_vector.begin(), cat_vector.end(), printCat());

	//random_shuffle 打乱容器顺序 可以加一个随机数种子来实现每次都是更新随机数
	//srand((unsigned int)time(NULL));
	cout << "************** random_shuffle ****************" << endl;
	random_shuffle(int_vector.begin(), int_vector.end());
	for_each(int_vector.begin(), int_vector.end(), printInt);
	cout << endl;

	random_shuffle(cat_vector.begin(), cat_vector.end());
	for_each(cat_vector.begin(), cat_vector.end(), printCat());

	//merge函数,将两个容器合并到一个新容器中去,合并的数组必须是有序的要么都是降序,要么都是升序
	//这个函数默认的排序规则是升序,要写成降序的要用谓词来实现。
	//最后一个参数就是声明的排序规则
	cout << "************** merge ****************" << endl;
	vector<int> v1;
	v1.emplace_back(200);
	v1.emplace_back(100);
	v1.emplace_back(20);
	vector<int> v2;
	v2.emplace_back(22);
	v2.emplace_back(21);
	v2.emplace_back(10);
	vector<int> merge_int;
	merge_int.resize(v1.size() + v2.size());
	merge(v1.begin(),v1.end(),v2.begin(),v2.end(),merge_int.begin(),greater<int>());
	for_each(merge_int.begin(), merge_int.end(), printInt);
	cout << endl;

	vector<Cat> cat1;
	vector<Cat> cat2;
	cat1.emplace_back(Cat("a", 300));
	cat1.emplace_back(Cat("b", 200));
	cat1.emplace_back(Cat("c", 100));
	cat2.emplace_back(Cat("d", 3000));
	cat2.emplace_back(Cat("e", 2000));
	cat2.emplace_back(Cat("f", 10));
	vector<Cat> merge_cat;
	merge_cat.resize(cat1.size() + cat2.size(), c1);
	merge(cat1.begin(), cat1.end(), cat2.begin(), cat2.end(), merge_cat.begin(),sortForCatAge_Down());
	for_each(merge_cat.begin(), merge_cat.end(), printCat());
}

拷贝替换算法

copy函数本质就是替换迭代器位置的数,要提前开辟空间。

class greatFive {
public:
	bool operator()(int val) {
		return val > 5;
	}
};
class greatCatAgeTen {
public:
	bool operator()(const Cat c) {
		return c.cat_age > 10;
	}
};
void test_swap() {
	vector<int> int_vector;
	int_vector.emplace_back(6);
	int_vector.emplace_back(5);
	int_vector.emplace_back(4);
	int_vector.emplace_back(3);
	int_vector.emplace_back(2);
	Cat c1("aa", 12);
	Cat c2("bb", 16);
	Cat c3("cc", 14);
	Cat c4("dd", 2);
	vector<Cat> cat_vector;
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c4);
	cat_vector.emplace_back(c2);
	cat_vector.emplace_back(c3);

	//replace函数,第三个参数是要被替换的数据,第四个参数是要更改的新地址。
	replace(int_vector.begin(), int_vector.end(), 4, 40);
	for_each(int_vector.begin(), int_vector.end(), printInt);
	cout << endl;

	Cat cReplace("w", 100);
	replace(cat_vector.begin(), cat_vector.end(), c1, cReplace);
	for_each(cat_vector.begin(), cat_vector.end(), printCat());

	//replace_if函数,第三个参数是一个谓词,按条件替换
	replace_if(int_vector.begin(), int_vector.end(), greatFive(),1000);
	for_each(int_vector.begin(), int_vector.end(), printInt);
	cout << endl;

	replace_if(cat_vector.begin(), cat_vector.end(), greatCatAgeTen(), cReplace);
	for_each(cat_vector.begin(), cat_vector.end(), printCat());

	//swap函数,交换两个容器的值,两个容器必须是同种类型,如果交换的时候两者的大小不一样无所谓
	vector<int> vSwap;
	vSwap.emplace_back(1111);
	swap(vSwap, int_vector);
	for_each(int_vector.begin(), int_vector.end(), printInt);
	cout << endl;
	for_each(vSwap.begin(), vSwap.end(), printInt);
	cout << endl;

	vector<Cat> catSwap;
	catSwap.emplace_back(Cat("swap",1000));
	swap(catSwap, cat_vector);
	for_each(cat_vector.begin(), cat_vector.end(), printCat());
	cout << endl;
	for_each(catSwap.begin(), catSwap.end(), printCat());

	//copy函数,将容器中数据拷贝到另一个容器中去。(替换当前位置)
	vector<int> vCopy;
	vCopy.emplace_back(1);
	vCopy.emplace_back(2);
	vCopy.resize(vCopy.size() + int_vector.size());//提前开辟空间
	copy(int_vector.begin(), int_vector.end(), vCopy.end() - 1);
	for_each(vCopy.begin(), vCopy.end(), printInt);
	cout << endl;

	vector<Cat> catCopy;
	catCopy.emplace_back(Cat("copy", 100));
	catCopy.resize(cat_vector.size() + catCopy.size(),c1);
	copy(cat_vector.begin(), cat_vector.end(), catCopy.end() - 1);//尾部追加
	for_each(catCopy.begin(), catCopy.end(), printCat());
}

算术生成以及集合算法

算法要包含头文件#include<numeric>

void test_my() {
	vector<int> int_vector;
	int_vector.emplace_back(6);
	int_vector.emplace_back(5);
	int_vector.emplace_back(4);
	int_vector.emplace_back(3);
	int_vector.emplace_back(2);
	Cat c1("aa", 12);
	Cat c2("bb", 16);
	Cat c3("cc", 14);
	Cat c4("dd", 2);
	vector<Cat> cat_vector;
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c1);
	cat_vector.emplace_back(c4);
	cat_vector.emplace_back(c2);
	cat_vector.emplace_back(c3);
	
	//accumulate函数,算一个容器的总和, 第三个参数是初始值
	int sum = accumulate(int_vector.begin(), int_vector.end(), 0);
	cout << sum << endl;

	//fill填充函数,将迭代器位置的数换成第三个参数
	fill(int_vector.begin(), int_vector.end(), 100);
	for_each(int_vector.begin(), int_vector.end(), printInt);
	cout << endl;

	//set_intersection    set_union   set_difference  使用前要先指定容器大小
	// 求两个容器的交集     并集          差集
	vector<int> v1;
	v1.emplace_back(30);
	v1.emplace_back(40);
	v1.emplace_back(50);
	v1.emplace_back(60);
	vector<int> v2;
	v2.emplace_back(40);
	v2.emplace_back(50);
	v2.emplace_back(60);
	v2.emplace_back(70);
	vector<int> vSet;
	vSet.resize(min(v1.size(), v2.size()));
	//这个地方要用 itEnd 因为这三个函数的返回值是交集到哪里就停止。
	vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vSet.begin());
	for_each(vSet.begin(), itEnd, printInt);
	cout << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值