C++笔记(39-42)

C++笔记(39-42)end


STL三大组件:容器、算法、迭代器

三十九、算法-函数对象

在这里插入图片描述

#include<iostream>
using namespace std;


class Myprint {
public:
	int num;
	Myprint() :num(0) {};

	void operator() (int n) {
		cout << n << endl;
		num++;
	}


};

int main() {
	Myprint my;
	my(10); // 函数对象
	my(10);
	my(10);
	my(10);
	cout << my.num << endl;

	Myprint you;
	you(18);
	you(18);
	you(18);
	cout << you.num << endl;
	return 0;
	/*output
		10
		10
		10
		10
		4
		18
		18
		18
		3*/

}

四十、算法-谓语predicate

谓语Predicate:
如果一个函数对象(仿函数)中,重载的()的返回值类型是boo1类型,这样的函数对象(仿函数)其实就是谓语Predicate.

find_if(start,end,predicate):从给定的范围中,查询满足条件的元素。如果找到了,返回这个元素的迭代器;如果没有找到,就返回end.

#include<algorithm> :: sort

sort(start,end,predicate):使用指定的大小比较规则,对指定范围的元素进行排序.

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;


class Student {
private:
	string _name;
	int _age;

public:
	Student(){}
	Student(string name, int age) :_name(name), _age(age) {}

	int age() {
		return _age;
	}

	void desc() {
		cout << "name: " << _name << " age: " << _age << endl;
	}
};

// 一元谓语
class Yonger {
public:
	bool operator() (Student& s) {
		return s.age() < 1;
	}
};

// 二元谓语
class Mycompare {
public:
	bool operator() (Student& s1, Student& s2) {
		return s1.age() < s2.age(); //从小到大排
	}

};



void test01() {
	vector<Student> v;
	v.push_back(Student("1", 19));
	v.push_back(Student("2", 17));
	v.push_back(Student("3", 18));
	v.push_back(Student("4", 20));
	v.push_back(Student("5", 19));
	v.push_back(Student("6", 11));
	v.push_back(Student("7", 12));
	v.push_back(Student("8", 14));
	
	// 要求找到第一个age < 18 的Student
	auto it = find_if(v.begin(), v.end(), Yonger());

	if (it == v.end()) {
		cout << "NO FIND" << endl;
	}
	else {
		(*it).desc();
	}

	// 要求从小到大排序
	sort(v.begin(), v.end(), Mycompare());

	for (Student& s : v) {
		s.desc();
	}

}

int main() {
	test01();
/*output
	NO FIND
	name : 6 age : 11
	name : 7 age : 12
	name : 8 age : 14
	name : 2 age : 17
	name : 3 age : 18
	name : 1 age : 19
	name : 5 age : 19
	name : 4 age : 20
*/
	return EXIT_SUCCESS;
}

四十一、内建函数对象

在这里插入图片描述在这里插入图片描述

四十二、算法

1.遍历算法 for_each

for_each 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象
for_each(iterator beg,iterator end,callbagk);

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

vector<int>* getVector() {
	vector<int>* v = new vector<int>();
	for (int i = 0; i < 10; i++) {
		v->push_back(i);
	}
	return v;
}

class Myprint {
public:
	void operator()(int i) {
		cout << i <<" ";
	}
};

void print(int i) {
	cout << i << " ";
}

void test() {
	// 获取到需要遍历的数据容器
	vector<int>* v = getVector();

	// 使用for_each算法进行遍历,使用到的是函数对象(仿函数)
	for_each(v->begin(), v->end(), Myprint()); 
	cout << endl;

	// 使用for_each算法进行遍历,使用到的是普通函数引用
	for_each(v->begin(), v->end(), print);

}

int main() {
	test();
	/*output
		0 1 2 3 4 5 6 7 8 9
		0 1 2 3 4 5 6 7 8 9
	*/
	return 0;
}

2.遍历算法 transform

transform算法 将指定容器区间元素搬运到另一容器中
注意 : transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器开始迭代器
@param end1 源容器结束迭代器
@param beg2 目标容器开始迭代器
@param _callback 回调函数或者函数对象
@return 返回目标容器迭代器
transform(iterator beg1,iterator end1, iterator beg2, _callback);
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.查找算法 find

find算法 查找元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找元素的位置
find(iterator beg, iterator end, value): 将每一个元素与 value 进行 == 比较,故有必要重载 == 运算符

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;


/*
find算法 查找元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找元素的位置
find(iterator beg, iterator end, value): 将每一个元素与 value 进行 == ,故有必要重载 == 运算符
*/

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	// 从这个容器中,查找5
	vector<int>::iterator it = find(v.begin(), v.end(), 5);
	if (it == v.end()) {
		cout << "没有找到指定的元素" << endl;
	}
	else {
		cout << "找到了指定的元素:" << *it << endl;
	}
}

class Student {
public:
	string name;
	int age;

	Student() = default;
	Student(string n, int a):name(n), age(a){}

	bool operator== (const Student& s) {
		return name == s.name && age == s.age;
	}

};

void test02() {
	vector<Student> v;
	v.push_back(Student("1", 19));
	v.push_back(Student("2", 17));
	v.push_back(Student("3", 18));
	v.push_back(Student("4", 20));
	v.push_back(Student("5", 19));
	v.push_back(Student("6", 11));
	v.push_back(Student("7", 12));
	v.push_back(Student("8", 14));
	vector<Student>::iterator it = find(v.begin(), v.end(), Student("8", 190));
	if (it == v.end()) {
		cout << "没有找到指定的Student" << endl;
	}
	else {
		cout << "找到了指定的Student:" << (*it).name << endl;
	}

}

int main() {
	//test01();
	test02();


	return EXIT_SUCCESS;
}

4.查找算法 find_if

find_if算法 条件查找
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param _callback 回调函数或者谓词(返回bo01类型的函数对象)
@return bool 查找返回true 否则false
find_if(iterator beg, iterator end, _callback):会将每一个元素带入到 callback 中来,不同于find 仅仅是使用 == 。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;


/*
find_if算法 条件查找
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回bo01类型的函数对象)
@return bool 查找返回true 否则false
find_if(iterator beg, iterator end, _callback);
*/

class Student {
private:
	string _name;
	int _age;

public:
	Student() {}
	Student(string name, int age) :_name(name), _age(age) {}

	int age() {
		return _age;
	}
	void desc() {
		cout << "name: " << _name << " age: " << _age << endl;
	}

};

// 一元谓语
class Yonger {
public:
	bool operator() (Student& s) {
		return s.age() < 18;
	}
};

void test01() {
	vector<Student> v;
	v.push_back(Student("1", 19));
	v.push_back(Student("2", 17));
	v.push_back(Student("3", 18));
	v.push_back(Student("4", 20));
	v.push_back(Student("5", 19));
	v.push_back(Student("6", 11));
	v.push_back(Student("7", 12));
	v.push_back(Student("8", 14));

	// 要求找到第一个age < 18 的Student
	auto it = find_if(v.begin(), v.end(), Yonger());

	if (it == v.end()) {
		cout << "NO FIND" << endl;
	}
	else {
		(*it).desc();
	}
}

int main() {
	test01();
	return EXIT_SUCCESS;
}

5.查找算法 adjacent_find

adjacent_find算法 查找相邻重复元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 可不用,类似于find,有必要重写 ==
回调函数或者谓词(返回boo1类型的函数对象)
@return 返回相邻元素的第一个位置的迭代器
adjacent find(iterator beg, iterator end, _callback);

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
/*
adjacent_find算法 查找相邻重复元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 可不用,类似于find,有必要重写 == 
                回调函数或者谓词(返回boo1类型的函数对象)
@return 返回相邻元素的第一个位置的迭代器
adjacent find(iterator beg, iterator end, _callback);
*/

void test01() {
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(2);
	v.push_back(5);
	v.push_back(5);
	v.push_back(6);
	v.push_back(1);
	auto it = adjacent_find(v.begin(), v.end());
	if (it == v.end()) {
		cout << "没有找到" << endl;
	}
	else {
		cout << "找到了:" << *it << endl;
	}
}

class Student {
public:
	string name;
	int age;
	Student() {}
	Student(string name, int age) :name(name), age(age) {}

	void desc() {
		cout << "name: " << name << " age: " << age << endl;
	}

	/*bool operator== (const Student& s) {
		return name == s.name && age == s.age;
	}*/
};

struct callback01 {
	bool operator() (const Student& s1, const Student& s2) {
		return s1.age == s2.age && s1.name == s2.name;
	}
};

void test02() {

	vector<Student> v;
	v.push_back(Student("1", 19));
	v.push_back(Student("2", 17));
	v.push_back(Student("3", 18));
	v.push_back(Student("4", 20));
	v.push_back(Student("4", 20));
	v.push_back(Student("2", 17));
	v.push_back(Student("5", 19));
	v.push_back(Student("5", 19));
	v.push_back(Student("6", 11));
	v.push_back(Student("5", 19));
	v.push_back(Student("7", 12));
	v.push_back(Student("8", 14));
	auto it = adjacent_find(v.begin(), v.end(), callback01());
	if (it == v.end()) {
		cout << "没有找到" << endl;
	}
	else {
		cout << "找到了:" << it->name << endl;
	}
}

int main() {
	//test01();
	test02();

	return EXIT_SUCCESS;
}

6.查找算法 binary_search

存在重载,可使用callback
在这里插入图片描述

7.查找算法 count & count_if

count算法 统计元素出现次数
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value回调函数或者谓词(返回bool类型的函数对象)
@return int返回元素个数
count(iterator beg,iterator end,value);
注意:如果比较的是自定义的类型(类、结构体),此时需要配合==运算符重载,类似于 find

count_if算法 统计元素出现次数
@param beg 容器开始迭代器
Cparam end 容器结束迭代器
@param callback 回调函数或者谓词(返回boo1类型的函数对象)
@return int返回元素个数
count_if(iterator beg,iterator end,callback);

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct JishuPredicate {
	bool operator()(int n) {
		return n % 2 == 0;
	}
};

int main() {
	int arr[] = { 1,2,3,4,6,78,2,3,5,6,9,4,2,1,1,1,35,56,7 };
	vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
	//查找7出现了多少次
	cout << count(v.begin(), v.end(),7) << endl;
	//查找有多少个奇数
	cout << count_if(v.begin(), v.end(), JishuPredicate()) << endl;

	return 0;
}

8.排序算法 sort

sort算法 容器元素排序
@param beg 容器1开始迭代器
@param end 容器1结束迭代器
@param_callback 默认升序; 回调函数或者谓词(返回bool类型的函数对象)
sort(iterator beg,iterator end,_callback)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Student {
private:
	string _name;
	int _age;

public:
	Student() {}
	Student(string name, int age) :_name(name), _age(age) {}

	int age() {
		return _age;
	}
	void desc() {
		cout << "name: " << _name << " age: " << _age << endl;
	}

};

struct print {
	void operator() (int i) {
		cout << i << " ";
	}
};

struct compare {
	bool operator()( Student& s1,  Student& s2) {
		return s1.age() < s2.age();
	}
};

void test02() {
	int arr[] = { 1,2,3,4,6,78,2,3,5,6,9,4,2,1,1,1,35,56,7 };
	vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
	for_each(v.begin(), v.end(), print());
	cout << endl;

	// 升序
	sort(v.begin(), v.end());
	for_each(v.begin(), v.end(), print());
	cout << endl;

	// 降序
	sort(v.begin(), v.end(), greater<int>());
	for_each(v.begin(), v.end(), print());
	cout << endl;

}

void test01() {
	vector<Student> v;
	v.push_back(Student("1", 19));
	v.push_back(Student("2", 17));
	v.push_back(Student("3", 18));
	v.push_back(Student("4", 20));
	v.push_back(Student("5", 19));
	v.push_back(Student("6", 11));
	v.push_back(Student("7", 12));
	v.push_back(Student("8", 14));

	sort(v.begin(), v.end(), compare());

	for (auto item : v) {
		item.desc();
	}
}

int main() {
	test01();
	//test02();
	return EXIT_SUCCESS;
}

9.排序算法 merge

merge算法 容器元素合并,并存储到另一容器中
注意 : 两个容器必须是有序的
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器

merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest.begin())

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

/*
merge算法 容器元素合并,并存储到另一容器中
注意 : 两个容器必须是有序的
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器

merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
*/

void print(int i) {
	cout << i << " ";
}

int main() {

	int arr1[] = { 1,3,5,7,9 };
	int arr2[] = { 0,2,4,6,8,10,12};
	vector<int> v1(arr1, arr1 + (sizeof(arr1) / sizeof(int)));
	vector<int> v2(arr2, arr2 + (sizeof(arr2) / sizeof(int)));
	for_each(v1.begin(), v1.end(), print);
	cout << endl;
	for_each(v2.begin(), v2.end(), print);
	cout << endl;

	vector<int> v3;
	v3.resize(v1.size() + v2.size());
	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
	for_each(v3.begin(), v3.end(), print);
	cout << endl;



	return 0;
}

10.排序算法 random_shuffle

random_shuffle算法 对指定范围内的元素随机调整次序
@param beg 容器开始迭代器
@param end 容器结束迭代器
random _shuffle(iterator beg,iterator end)
可以设置随机种子srand(int)
在这里插入图片描述

11.排序算法 reverse

reverse算法 反转指定范围的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
reverse(iterator beg, iterator end)

在这里插入图片描述

12.copy & replace & replace_if & swap

copy算法 将容器内指定范围的元素拷贝到另一容器中
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param dest 目标起始迭代器
copy(iterator beg,iterator end, iterator dest.begin())

replace算法 将容器内指定范围的旧元素修改为新元素
容器开始迭代器
@param beg
@param end 容器结束迭代器
@param oldvalue l元素
@param oldvalue 新元素
replace(iterator beg,iterator end,oldvalue,newvalue)

replace_if算法 将容器内指定范围满足条件的元素替换为新元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback函数回调或者谓词(返回B001类型的函数对象)
@param oldvalue 新元素
replace_if(iterator beg,iterator end,callback,newvalue)

swap算法 互换两个容器的元素
@param c1容器1
@param c2容器2
swap(container c1, container c2)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct Print {
	void operator()(int i) {
		cout << i << " ";
	}
};

void test01() {
	vector<int> v1;
	v1.push_back(10);
	v1.push_back(12);
	v1.push_back(15);
	v1.push_back(9);
	v1.push_back(7);
	vector<int> v2;
	v2.resize(v1.size());

	copy(v1.begin(), v1.end(), v2.begin());
	for_each(v2.begin(), v2.end(), Print());
	cout << endl;
}


void test02() {
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(1);
	v.push_back(3);
	v.push_back(1);
	// 需求:将容器中的1都替换成100
	replace(v.begin(),v.end(),1,100);
	for_each(v.begin(), v.end(),Print());
	cout << endl;

}

struct Filter {
	bool operator()(int i) {
		return i % 2 == 1;
	}
};

void test03() {
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);
	// 需求:将容器中的所有的奇数,替换成100
	replace_if(v.begin(),v.end(),Filter(),100);
	for_each(v.begin(), v.end(),Print());
}


void test04() {
	int arr1[] = { 1,3,5,7,9 };
	int arr2[] = { 2,4,6,8,0,121,4,16 };
	vector<int> v1(arr1, arr1 + (sizeof(arr1) / sizeof(int)));
	vector<int> v2(arr2, arr2 + (sizeof(arr2) / sizeof(int)));
	swap(v1, v2);
	for_each(v1.begin(), v1.end(), Print());
	cout << endl;
	for_each(v2.begin(),v2.end(), Print());
}

int main() {
	//test01();
	//test02();
	//test03();
	test04();

	return 0;
}

13.accumulate & fill

accumulate算法 计算容器元素累计总和+value
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value累加值
include numeric :: accumulate(iterator beg,iterator end,value)

fill算法 向容器中添加元素,覆盖之前的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t填充元系
fill(iterator beg,iterator end, value)

#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
using namespace std;

struct print {
	void operator() (int i){
		cout << i << " ";
	}
};

int main() {
	vector<int> v(5, 10);
	// 10 10 10 10 10 100 相加 = 150
	cout << accumulate(v.begin(), v.end(), 100) << endl;

	// 前 2 个元素替换为 9
	fill(v.begin(), v.begin()+2, 9);
	for_each(v.begin(), v.end(), print());

	/*
	output
		150
		9 9 10 10 10
	*/
	return 0;
}

14.集合算法 set_intersection union difference

set_intersection算法 求两个set集合的交集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)

set_union算法 求两个set集合的并集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
set _union(iterator begl, iterator end1, iterator beg2, iterator end2, iterator dest)

set_difference算法 求两个set集合的差集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
set difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
v1在前,v2在后,求:v1有的, v2没有
v2在前,v1在后,求:v2有的, v1没有

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;



int main() {
	int arr1[] = {1,2,4,65,7,8,8,9,6,46,7,89,0};
	int arr2[] = {1,3,5,6,2,7,8,9,56,3,3,4,4,5,6,8};
	
	vector<int> v1(arr1, arr1 + (sizeof(arr1) / sizeof(int)));
	vector<int> v2(arr2, arr2 + (sizeof(arr2) / sizeof(int)));

	sort(v1.begin(), v1.end());
	sort(v2.begin(), v2.end());
	for (const int& ele : v1) {
		cout << ele << " ";
	}
	cout << endl;

	for (const int& ele : v2) {
		cout << ele << " ";
	}
	cout << endl;

	// 求交集
	vector<int> res1;
	res1.resize(min(v1.size(),v2.size()));
	//返回的是交集中最后一个元素的下一位的迭代器
	vector<int>::iterator it1 = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), res1.begin());
	for (vector<int>::iterator it = res1.begin(); it != it1; it++) {
		cout << *(it) << " ";
	}
	cout << endl;

	// 求并集
	vector<int> res2;
	res2.resize(v1.size() + v2.size());
	vector<int>::iterator it2 = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), res2.begin());
	for (vector<int>::iterator it = res2.begin(); it != it2; it++) {
		cout << *(it) << " ";
	}
	cout << endl;

	// 求差集
	vector<int>res3;
	res3.resize(max(v1.size(),v2.size()));
	// v1在前,v2在后,求:v1有的, v2没有
	vector<int>::iterator it3 = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), res3.begin());
	for (vector<int>::iterator it = res3.begin(); it != it3; it++) {
		cout << *(it) << " ";
	}
	cout << endl;
	// v2在前,v1在后,求:v2有的, v1没有
	vector<int>::iterator it4 = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), res3.begin());
	for (vector<int>::iterator it = res3.begin(); it != it4; it++) {
		cout << *(it) << " ";
	}
	cout << endl;
	/*
	output
		0 1 2 4 6 7 7 8 8 9 46 65 89
		1 2 3 3 3 4 4 5 5 6 6 7 8 8 9 56
		1 2 4 6 7 8 8 9
		0 1 2 3 3 3 4 4 5 5 6 6 7 7 8 8 9 46 56 65 89
		0 7 46 65 89
		3 3 3 4 5 5 6 56
	*/
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值