0
点赞
收藏
分享

微信扫一扫

C++经典问题_27 STL(十一) 常用算法

ixiaoyang8 2022-04-16 阅读 80
c++c语言

文章目录

一. 常用算法概述

二. 常用的遍历算法

① for_each 遍历容器

原型:

/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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


void print_01(int val)
{
	cout << val << " ";
}

class Print_02
{
public:
	void operator()(int val)
	{
		cout << val << " ";
	}
};

void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	// 使用for_each遍历
	for_each(v.begin(), v.end(),print_01);
	cout << endl;

	// 使用仿函数,注意仿函数使用的时候比普通的函数多个括号
	// 这里为啥多个括号,其实Print_02本身不是哥函数,Print_02()这里会返回
	// operator()这个函数
	for_each(v.begin(), v.end(), Print_02());
	cout << endl;
}

int main()
{
	test_01();
	system("pause");
	return 0;
}

② transform 搬运容器到另外一个容器中,并且搬运的过程中可以通过普通函数或者仿函数进行操作

函数原型:

beg1 源容器开始迭代器
end1 源容器结束迭代器
beg2 目标容器开始迭代器
_func 普通的函数或者是函数对象(仿函数)

注意:

/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

class Transform
{
public:
	int operator()(int val)
	{
		return val;
	}
};

void my_print(int val)
{
	cout << val << " ";
}

// 常用遍历算法 transform
void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	vector<int> vTarget; // 目标容器
	vTarget.resize(v.size()); // 这一步一定要有,不然容易报错
	// 开始搬运
	transform(v.begin(), v.end(), vTarget.begin(), Transform());

	// 遍历
	for_each(vTarget.begin(), vTarget.end(), my_print);
	cout << endl;
}

int main()
{

	test_01();
	system("pause");
	return 0;
}

三. 常用的查找算法

① find

原型:

  • 按值查找元素,找到了返回指定位置迭代器,找不到返回结束位置迭代器
  • beg 开始迭代器
  • end 结束迭代器
  • value 查找的元素
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

class Person
{
public:
	Person(string name, int age)
	{
		this->mName = name;
		this->mAge = age;
	}
	// 重载 == 运算符,find函数在查找的时候会自动调用
	bool operator==(const Person p)
	{
		return this->mName == p.mName && this->mAge == p.mAge;
	}
	string mName;
	int mAge;
};

void test_01(void)
{
	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 << "成功找到了 " << *it << endl;
	}
	else
	{
		cout << "未找到!" << endl;
	}

	// 查找自定义的数据类型的时候,自定义的数据类型,要重载==比较运算符
	// 因为find查找的时候,就是去调用这个运算符函数去对比的
	Person p1("A", 10);
	Person p2("B", 20);
	Person p3("C", 30);

	vector<Person> v2;
	v2.push_back(p1);
	v2.push_back(p2);
	v2.push_back(p3);

	vector<Person>::iterator it2 = find(v2.begin(), v2.end(), p2);
	if (it2 == v2.end())
	{
		cout << "未找到 p2" << endl;
	}
	else
	{
		cout << "找到了p2: " << " 姓名: " << it2->mName << " 年龄: " << it2->mAge << endl;
	}
}
int main()
{
	test_01();

	system("pause");
	return 0;
}

结果:

② find_if

函数原型

  • 按值进行查找元素,找到了返回指定位置的迭代器,找不到返回结束迭代器位置
  • begin 开始迭代器
  • end 结束迭代器位置
  • _Pred 函数或者谓词(返回bool类型的仿函数)
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

// 创建一元谓词
class GreaterFive
{
public:
	bool operator()(int val)
	{
		return val > 5;
	}
};

// 1.查找内置的数据类型
void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	vector<int>::iterator it =  find_if(v.begin(), v.end(), GreaterFive());
	if (it != v.end())
	{
		cout << "找到了大于5的数,值为: " << *it << endl;
	}
	else
	{
		cout << "未找到大于5的数" << endl;
	}

}


// 查找自定义的数据类型
class Person
{
public:
	Person(string name, int age)
	{
		this->mName = name;
		this->mAge = age;
	}
	string mName;
	int mAge;
};


class Greater20
{
public:
	bool operator()(const Person p)
	{
		return p.mAge > 20;
	}

};

void test_02(void)
{
	Person p1("A", 10);
	Person p2("B", 20);
	Person p3("C", 30);
	Person p4("D", 40);
	Person p5("E", 50);
	Person p6("F", 60);
	vector<Person> v;
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);
	v.push_back(p6);

	vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20());
	if (it != v.end())
	{
		cout << "查找成功: " << "姓名: " << it->mName << " 年龄: " << it->mAge << endl;
	}
	else
	{
		cout << "查找失败!" << endl;
	}

}

int main()
{
	test_01();
	test_02();
	system("pause");
	return 0;
}

结果:

③ adjacent_find

原型:

  • 查找相邻重复元素,返回相邻重复元素的第一个位置的迭代器,如果没有返回end();
  • begin: 开始迭代器
  • end: 结束迭代器
  • 可以用这个算法来删除重复元素,如果找到了重复元素就通过erase删除
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

void print_vector(const vector<int> &v)
{
	for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

void test_01(void)
{
	vector<int> v;
	v.push_back(2);
	v.push_back(2);
	v.push_back(0);
	v.push_back(0);
	v.push_back(1);
	v.push_back(1);
	v.push_back(3);
	v.push_back(3);

	// 查找相邻的重复元素,然后删除
	vector<int>::iterator it =  adjacent_find(v.begin(), v.end());

	while (it != v.end())
	{
		cout << "找到了重复元素: " << *it << endl;
		v.erase(it);
		it = adjacent_find(v.begin(), v.end());
	}
	
	cout << "重复元素删除之后的结果: " << endl;
	print_vector(v);

}

int main()
{
	test_01();

	system("pause");
	return 0;
}

结果:

④ binary_search

原型:

  • 查找指定的元素,查找到返回true,否则返回false
  • 注意: 在无序序列中不可用
  • begin: 开始迭代器
  • end: 结束迭代器
  • value: 查找的元素
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	// 查找元素中是否有9
	bool ret = binary_search(v.begin(), v.end(), 9);
	if (ret)
	{
		cout << "找到了!" << endl;
	}
	else
	{
		cout << "未找到!" << endl;
	}

	v.push_back(2); // 如果是无序的序列,结果是未知的
	ret = binary_search(v.begin(), v.end(), 9);
	if (ret)
	{
		cout << "找到了!" << endl;
	}
	else
	{
		cout << "未找到!" << endl;
	}
}


int main()
{

	test_01();
	system("pause");
	return 0;
}

结果:

⑤ count

原型:

  • 统计元素出现次数
  • begin 开始迭代器
  • end 结束迭代器
  • value 统计的元素

注意:

/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include<string>
class Person
{
public:
	Person(string name, int age)
	{
		this->mName = name;
		this->mAge = age;
	}
	// 根据年龄作为比较规则
	bool operator==(const Person p)
	{
		return this->mAge == p.mAge;
	}

public:
	string mName;
	int mAge;
};

// 1. 统计内置数据类型
// 2. 统计自定义的数据类型的个数
void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	v.push_back(1);
	v.push_back(1);

	int num = count(v.begin(), v.end(), 1);
	cout << "1 的元素个数: " << num << endl;


	Person p1("A", 10);
	Person p2("B", 20);
	Person p3("C", 10);
	Person p4("D", 10);
	Person p5("E", 30);
	vector<Person> v2;
	v2.push_back(p1);
	v2.push_back(p2);
	v2.push_back(p3);
	v2.push_back(p4);
	v2.push_back(p5);

	// 如果是要统计年龄相等的话
	num = count(v2.begin(), v2.end(), p1);
	cout << "和p1年龄相同的人数: " << num << endl;

}

int main()
{
	test_01();

	system("pause");
	return 0;
}

⑥ count_if

原型:

  • 按照条件统计元素出现的次数
  • begin 开始迭代器
  • end 结束迭代器
  • _Pred 谓词 (可以是普通的函数,也可以是仿函数(函数对象))
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
bool greater_five(int val)
{
	return val > 5;
}

class GreaterSix
{
public:
	// 创建谓词
	bool operator()(int val)
	{
		return val > 6;
	}
};

void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	// 普通的函数作为判断条件
	int num = count_if(v.begin(), v.end(), greater_five);
	cout << "大于5的个数: " << num << endl;

	// 谓词作为判断条件
	num = count_if(v.begin(), v.end(), GreaterSix());
	cout << "大于6的个数: " << num << endl;
	
}

int main()
{

	test_01();
	system("pause");
	return 0;
}

四. 常用的排序算法

① sort

原型:
sort(iterator begin,iterator end,_Pred);

  • begin: 开始迭代器
  • end: 结束迭代器
  • _Pred: 谓词
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

void print_vector(const vector<int>& v)
{
	for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

bool my_compare(int a, int b)
{
	return a > b;
}

class MyCompare
{
public:
	// 创建谓词
	bool operator()(int v1, int v2)
	{
		return abs(v1) > abs(v2);
	}
};

void test_01(void)
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(40);
	v.push_back(50);
	v.push_back(30);

	// 默认排序,从小到大
	cout << "默认排序: " << endl;
	sort(v.begin(), v.end());
	print_vector(v);

	// 指定排序规则,先使用普通的函数去指定,降序排列
	cout << "普通的函数指定降序排列: " << endl;
	sort(v.begin(), v.end(), my_compare);
	print_vector(v);

	// 添加几个负数,然后按照谓词,按照绝对值的升序进行排列
	v.push_back(-10);
	v.push_back(-20);
	v.push_back(-30);
	v.push_back(-40);

	cout << "谓词按照绝对值降序进行排序: " << endl;
	sort(v.begin(), v.end(), MyCompare());
	print_vector(v);

}

int main()
{

	test_01();
	system("pause");
	return 0;
}

结果:
在这里插入图片描述

② random_shuffle

原型:

  • 指定范围内的元素的随机调整次序
  • begin 开始迭代器
  • end 结束迭代器
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

void print_vector(const vector<int>& v)
{
	for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	print_vector(v);

	// 打乱顺序
	random_shuffle(v.begin(), v.end());
	cout << "顺序打乱以后: " << endl;
	print_vector(v);
}

int main()
{

	test_01();
	system("pause");
	return 0;
}

④ merge

原型:

  • 容器元素合并,并存储到另外一个容器中
  • 注意: 两个容器必须是有序的,合并之后依旧是有序的.并且要提前给dest分配内存空间,使用resize.
  • begin1 容器1的开始迭代器
  • end1 容器1的结束迭代器
  • begin2 容器2的开始迭代器
  • end2 容器2的结束迭代器
  • dest 目标容器的开始迭代器
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

void my_print(int val)
{
	cout << val << " ";
}

void print_vector(const vector<int> &v)
{
	for_each(v.begin(), v.end(), my_print);
	cout << endl;
}

void test_01(void)
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
		v2.push_back(i + 1);
	}
	// 进行合并
	vector<int> vTarget;
	// 注意: 合并之前,首先是要分配内存空间,注意最后一个参数不是目标容器,而是目标容器的起始迭代器
	vTarget.resize(v1.size() + v2.size());
	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	cout << "合并后: " << endl;
	print_vector(vTarget);

}
int main()
{
	test_01();
	system("pause");
	return 0;
}

⑤ reverse算法

原型:

  • 翻转制动范围内的元素
  • begin 开始迭代器
  • end 结束迭代器
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

void my_print(int val)
{
	cout << val << " ";
}

void print_vector(const vector<int> &v)
{
	for_each(v.begin(), v.end(), my_print);
	cout << endl;
}

void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	// 原容器
	cout << "原容器: " << endl;
	print_vector(v);

	// 打乱顺序
	random_shuffle(v.begin(), v.end());
	cout << "打乱顺序: " << endl;
	print_vector(v);

	// 反转
	reverse(v.begin(), v.end());
	cout << "反转: " << endl;
	print_vector(v);
}
int main()
{

	test_01();
	system("pause");
	return 0;
}

结果:

五. 常用的拷贝和替换算法

① copy

原型:

  • 拷贝容器到目标容器,需要指定目标容器的大小,也就是说需要使用resize()指定目标容器大小
  • begin 开始迭代器
  • end 结束迭代器
  • dest 目标起始迭代器
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void my_print(int val)
{
	cout << val << " ";
}

void print_vector(const vector<int> &v)
{
	for_each(v.begin(), v.end(), my_print);
	cout << endl;
}

void test_01(void)
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	v2.resize(v1.size()-2); // 这个resize之后的大小,要保证可以存放拷贝过来的元素
	//v2.resize(v1.size()); // 这种情况下,如果拷贝过来的数据,不到size()大小,默认是填充0,后面
	// v2.resize(v1.size() - 3); //空间不够,会报错

	// 将v1的内容,拷贝到v2当中,并且去除掉收尾
	copy(++v1.begin(), --v1.end(),v2.begin());
	cout << "v1 = " << endl;
	print_vector(v1);
	cout << "v2 = " << endl;
	print_vector(v2);
}

int main()
{
	test_01();

	system("pause");
	return 0;
}

结果:
在这里插入图片描述

② replace

原型:

  • 将区间内旧元素,替换成新元素
  • begin 开始迭代器
  • end 结束迭代器
  • oldValue 旧元素
  • newValue 新元素
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

void print_vector(const vector<int> & v)
{
	for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i % 3);
	}
	cout << "原容器: " << endl;
	print_vector(v);

	// 将容器中的0全部替换为30
	replace(v.begin(), v.end(), 0, 30);
	cout << "替换后的容器: " << endl;
	print_vector(v);
}
int main()
{

	test_01();

	system("pause");
	return 0;
}

③ replace_if

原型:

  • 按照条件替换元素,满足条件的替换成指定元素
  • begin 开始迭代器
  • end 结束迭代器
  • _pred 谓词 (或者是普通的函数)
  • newValue 替换的新元素
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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


void my_print(int val)
{
	cout << val << " ";
}
void print_vector(const vector<int> &v)
{
	for_each(v.begin(), v.end(), my_print);
	cout << endl;
}

bool change_val(int val)
{
	return val % 2 == 0;
}

class ChangeVal
{
public:
	ChangeVal()
	{

	}
	// 创建谓词,如果是奇数,返回True
	bool operator()(int val)
	{
		if (val % 2 != 0)
		{
			mCount++;
		}
		return val % 2 != 0;
	}
	static int mCount;
};
int ChangeVal::mCount = 0;

void test_01(void)
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	cout << "原容器: " << endl;
	print_vector(v);

	// 使用普通函数作为判断条件,进行替换,将所有的偶数都变成0
	replace_if(v.begin(), v.end(), change_val,0);
	cout << "将偶数全部变为0之后: " << endl;
	print_vector(v);

	// 使用谓词,将所有的奇数都变成-1,并且统计奇数的个数
	ChangeVal change_val = ChangeVal();
	replace_if(v.begin(), v.end(),change_val, -1); // 注意这里调用的不是change_val是change_val的一个副本
	// 使用完就消失了,所以这里统计的个数依旧是0,如果想要正确的统计,要使用static
	cout << "替换后: 奇数的个数: " << change_val.mCount << endl;
	print_vector(v);
}

int main()
{

	test_01();
	system("pause");
	return 0;
}

结果:

④ swap

原型:

  • 互换两个容器的元素
  • c1的容器1
  • c2的容器2
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
void my_print(int val)
{
	cout << val << " ";
}
void test_01(void)
{
	vector<int> v1;
	vector<int> v2;

	for (int i = 0; i < 10; i++)
	{
		i % 2 == 0 ? v1.push_back(i) : v2.push_back(i);
	}

	cout << "互换前: " << endl;
	cout << "v1 = ";
	for_each(v1.begin(), v1.end(), my_print);
	cout << endl;
	cout << "v2 = ";
	for_each(v2.begin(), v2.end(), my_print);
	cout << endl;

	// 交换元素
	v1.swap(v2);
	cout << "互换后: " << endl;
	cout << "v1 = ";
	for_each(v1.begin(), v1.end(), my_print);
	cout << endl;
	cout << "v2 = ";
	for_each(v2.begin(), v2.end(), my_print);
	cout << endl;
}

int main()
{

	test_01();
	system("pause");
	return 0;
}

六. 常用的算术生成算法

计算区间内容器之和: accumulate

函数原型:

  • 计算容器元素累计总和
  • begin 开始迭代器
  • end 结束迭代器
  • value 起始值
  • func 为操作方式,默认是使用plus进行相加,如果是自定义的数据类型,需要自己添加操作符

注意:

/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

class Person
{
public:
	Person(string name, int score)
	{
		this->mName = name;
		this->mScore = score;
	}
	
public:
	string mName;
	int mScore;
};



int person_add(int val, const Person &p)
{
	return val + p.mScore;
}

void test_01(void)
{
	// 内置类型的求和
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	// 求和
	cout << "v的所有元素之和: " << accumulate(v.begin(), v.end(), 0) << endl;

	// 自定义类型的求和
	Person p1("A", 68);
	Person p2("B", 79);
	Person p3("C", 90);
	Person p4("D", 100);
	vector<Person> v2;
	v2.push_back(p1);
	v2.push_back(p2);
	v2.push_back(p3);
	v2.push_back(p4);
	// 求平均分,因为是自定义类型,要重载加号运算符
	int sumScore = accumulate(v2.begin(), v2.end(), 0,person_add);
	cout << "总分: " << sumScore << " 平均分: " << sumScore / v2.size() << endl;
}

int main()
{
	test_01();

	system("pause");
	return 0;
}

fill算法

原型:

  • 想容器中填充元素
  • begin 开始迭代器
  • end 结束迭代器
  • value 填充的值
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

#include <iostream>
using namespace std;
#include<vector>
#include<numeric>
#include<algorithm>
class MyPrint
{
public:
	void operator()(float val)
	{
		cout << val << " ";
	}
};

void test_01(void)
{
	vector<float> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	cout << "原容器: " << endl;
	for_each(v.begin(), v.end(), MyPrint());
	cout << endl;

	// 除了两头,将中间的全部填充为平均值
	float aver = accumulate(v.begin(), v.end(), 0) /float(v.size());
	cout << "aver: " << aver << endl;
	
	fill(++v.begin(), --v.end(), aver);
	cout << "填充平均值后: " << endl;
	for_each(v.begin(), v.end(), MyPrint());
	cout << endl;
}
int main()
{
	test_01();

	system("pause");
	return 0;
}

七. 常用的集合算法

① set_intersection

原型:

注意:

/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

void print_vector(const vector<int> &v)
{
	for (int i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;
}

void test_01(void)
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i); // 0~9
		v2.push_back(i + 5);// 5 ~ 14
	}
	cout << " v1 = ";
	print_vector(v1);
	cout << "v2 = ";
	print_vector(v2);

	vector<int> vTarget;
	// 需要开辟内存空间,最大需要容量为v1和v2的size的最小值
	vTarget.resize(min(v1.size(), v2.size()),-1000);
	set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	// 求完交集以后,要把后面默认的-1000多出来的元素删除掉
	vector<int>::iterator it = find(vTarget.begin(), vTarget.end(), -1000);
	if(it != vTarget.end())
	{
		vTarget.erase(it, vTarget.end());
	}
	cout << "v1 和 v2 的交集 = ";
	print_vector(vTarget);
}


int main()
{
	test_01();
	system("pause");
	return 0;
}

② set_union

原型:

  • 求两个集合的并集
  • 两个集合必须是有序的序列
  • begin1 容器1的起始迭代器
  • end1 容器1的结束迭代器
  • begin2 容器2的起始迭代器
  • end2 容器2的结束迭代器
  • dest 目标容器的起始迭代器

注意:

  1. 两个容器必须有序(并且是升序,亲测过,倒序不行)
  2. 目标容器需要指定大小, 大小定义为两个size()之和
  3. 如果并集小于目标容器,目标容器末尾会默认填充0,可以填充一个不在集合1和集合2的值,最后删除掉
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>

class MyPrint
{
public:
	void operator()(int val)
	{
		cout << val << " ";
	}
};

void test_01(void)
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i); // 0~9
		v2.push_back(i + 8); // 8 ~ 17
	}
	//reverse(v1.begin(), v1.end()); // 倒序不行
	//reverse(v2.begin(),v2.end()); // 倒序不行
	// 求并集
	cout << "v1 = ";
	for_each(v1.begin(), v1.end(), MyPrint());
	cout << endl;
	cout << "v2 = ";
	for_each(v2.begin(), v2.end(), MyPrint());
	cout << endl;

	cout << "v1 和 v2 的并集: " << endl;
	vector<int> vTarget;
	// 目标容器的最大size是v1的size和v2的size之和,这个时候v1和v2没有重复元素
	vTarget.resize(v1.size() + v2.size(), -1000);
	// 求并集
	set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	vector<int>::iterator it = find(vTarget.begin(), vTarget.end(), -1000);
	if (it != vTarget.end())
	{
		vTarget.erase(it, vTarget.end());
	}

	for_each(vTarget.begin(), vTarget.end(), MyPrint());
	cout << endl;
}

int main()
{

	test_01();
	system("pause");
	return 0;
}

③ set_difference

原型:

  • 两个集合必须是有序的(必须是升序)
  • begin1 容器1的开始迭代器
  • end2 容器1的结束迭代器
  • begin2 容器2的开始迭代器
  • end2 容器2的结束迭代器
  • dest 目标容器的开始迭代器

注意:

  • 差集是有顺序的v1和v2的差集, v2和v1的差集的结果大部分的时候都是不一样的
  • 差集计算的时候,两个集合必须是升序,然后结果也是升序
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/

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

class MyPrint
{
public:
	void operator()(int val)
	{
		cout << val << " ";
	}
};

void test_01(void)
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i); // 0~9
		v2.push_back(i + 5); // 5 ~ 14;
	}
	cout << "v1 = ";
	for_each(v1.begin(), v1.end(), MyPrint());
	cout << endl;
	cout << "v2 = ";
	for_each(v2.begin(), v2.end(), MyPrint());
	cout << endl;

	vector<int> vTarget;
	vTarget.resize(max(v1.size(), v2.size()),-1000);
	set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	// 求v1和v2的差集,并且去除掉后面的无效值
	vector<int>::iterator it = find(vTarget.begin(), vTarget.end(), -1000);
	if (it != vTarget.end())
	{
		vTarget.erase(it, vTarget.end());
	}
	cout << "v1 和 v2 的差集: ";
	for_each(vTarget.begin(), vTarget.end(), MyPrint());
	cout << endl;
	vTarget.resize(max(v1.size(), v2.size()), -1000);
	// 求v2和v1的差集
	set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
	it = find(vTarget.begin(), vTarget.end(), -1000);
	if (it != vTarget.end())
	{
		vTarget.erase(it, vTarget.end());
	}
	cout << "v2 和 v1 的差集: ";
	for_each(vTarget.begin(), vTarget.end(), MyPrint());
	cout << endl;

}

int main()
{

	test_01();
	system("pause");
	return 0;
}

结果:
在这里插入图片描述

举报

相关推荐

0 条评论