(C++学习笔记十七)STL 之 算法(遍历 查找 排序 拷贝 集合)

本文深入探讨了C++ STL中的各类算法,包括遍历、查找、排序等,并通过实例展示了如何使用这些算法来高效地处理容器中的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

十九.STL 之 算法

代码片内有详解, 目录:

// 一. 常用遍历算法

// 二. transform

// 三. 常用查找算法

// 四. 常用排序算法

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

// 六. 常用算术生成算法

// 七. 常用集合算法

1.Code :

#include<iostream>
using namespace std;
#include <algorithm> // algorithm : 算法
#include <vector>
#include<ctime>
#include<numeric>//算术生成算法属于小型算法

//    一. 常用遍历算法
//
//for_each //遍历容器

//函数原型:
//
//for_each(iterator beg, iterator end, _func);

// beg 开始迭代器

// end 结束迭代器

// _func 函数或者函数对象

//普通函数
void Display1(int num)
{
	cout << num << " ";
}
//函数对象
class Display2
{
public:
	void operator()(int num)
	{
		cout << num << " ";
	}
};


void test()
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	//普通函数
	for_each(v.begin(),v.end(),Display1);
	cout << endl;
	//函数对象
	for_each(v.begin(), v.end(), Display2());
	cout << endl;
}

//    二. transform
//搬运容器到另一个容器中
//函数原型:
//
//transform(iterator beg1, iterator end1, iterator beg2, _func);
beg1 源容器开始迭代器
//
end1 源容器结束迭代器
//
beg2 目标容器开始迭代器
//
_func 函数或者函数对象



//    三. 常用查找算法
//算法简介:
//
//find //查找元素  
//find(iterator beg, iterator end, value); 
// value 查找的元素

//find_if //按条件查找元素
//find_if(iterator beg, iterator end, _Pred);
// _Pred 函数或者谓词(返回bool类型的仿函数)

//adjacent_find //查找相邻重复元素
// adjacent_find(iterator beg, iterator end);  //adjacent : 邻
// 查找相邻重复元素,返回相邻元素的第一个位置的迭代器


//binary_search //二分查找法
// bool binary_search(iterator beg, iterator end, value); // binary : 二元
// 查找指定的元素,查到 返回true 否则false
//*总结:**二分查找法查找效率很高,值得注意的是查找的容器中元素必须的有序序列


//count //统计元素个数
//count(iterator beg, iterator end, value);
//总结: 统计自定义数据类型时候,需要配合重载 operator==

//count_if //按条件统计元素个数
//count_if(iterator beg, iterator end, _Pred);
// _Pred 谓词

class Printf
{
public:
	void operator()(int num)
	{
		cout << num << " ";
	}
};

class Transform
{
public:
	int operator()(int num)
	{
		cout << num << " ";
		return num;
	}
};

class gread
{
public:
	int operator()(int num,int num1)
	{
		return num > num1;
	}
};

class GreadFive
{
public:
	bool operator()(int num)
	{
		return num > 5;
	}
};

//自定义数据类型
class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
	bool operator==(const Person& p)
	{
		if (this->m_Age == p.m_Age)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	string m_Name;
	int m_Age;
};

class GreatTen
{
public:
	bool operator()(int num)
	{
		return num >= 10;
	}
};

class AgeLess35
{
public:
	bool operator()(const Person& p)
	{
		return p.m_Age < 35;
	}
};

void test2()
{
	int sd;

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

	for_each(v.begin(),v.end(),Printf());
	cout << endl;

	vector<int> v1;

	v1.resize(v.size());//标容器需要提前开辟空间
	transform(v.begin(),v.end(),v1.begin(), Transform());
	cout << endl;

	sort(v1.begin(), v1.end(), gread()); // 重 新排序
	for_each(v1.begin(), v1.end(), Printf());
	cout << endl;

	vector<int>::iterator it = find(v.begin(),v.end(),9);
	if (it == v.end()) { cout << "无" << endl; }
	else cout << "有 " << *it << endl;
	// find 也可以查找类

	it = find_if(v.begin(),v.end(),GreadFive());
	cout << *it << endl;

	v.push_back(2123);
	v.push_back(2123);
	it = adjacent_find(v.begin(), v.end());
	cout << "adjacent_find *it = " << *it << endl;

	bool yu = binary_search(v.begin(), v.end(),18);
	cout << "binary_search yu = " << yu << endl;

	v.push_back(2123);
	v.push_back(2123);
	sd = count(v.begin(), v.end(), 2123);
	cout << "count sd = " << sd << endl;

	vector<Person> v6;

	Person p1("刘备", 35);
	Person p2("关羽", 35);
	Person p3("张飞", 35);
	Person p4("赵云", 30);
	Person p5("曹操", 25);

	v6.push_back(p1);
	v6.push_back(p2);
	v6.push_back(p3);
	v6.push_back(p4);
	v6.push_back(p5);
	Person p("诸葛亮", 35);

	int num = count(v6.begin(), v6.end(), p);
	cout << "count(v6.begin(), v6.end(), p); num = " << num << endl;

	for_each(v.begin(), v.end(), Printf());
	num = count_if(v.begin(), v.end(), GreatTen());
	cout << "count_if num = " << num << endl;

	num = count_if(v6.begin(), v6.end(), AgeLess35());
	cout << "小于35岁的个数:" << num << endl;
}


//    四. 常用排序算法
//
//sort //对容器内元素进行排序
//sort(iterator beg, iterator end, _Pred);
// _Pred 谓词

//random_shuffle //洗牌 指定范围内的元素随机调整次序
//random_shuffle(iterator beg, iterator end);


//merge // 容器元素合并,并存储到另一容器中
//merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// dest 目标容器开始迭代器
// 注意: 两个容器合并时元素必须排列有序
// 注意: 两个容器 元素 的排序规则必须相同 (由小到大)

//reverse // 反转指定范围的元素
//reverse(iterator beg, iterator end);

class Grater1
{
public:
	bool operator()(int& a, int& b)
	{
		return a > b;
	}
};
void test3()
{
	srand((unsigned int)time(NULL));// 随机种子

	//sort //对容器内元素进行排序

	vector<int> v;
	v.push_back(48);
	v.push_back(87);
	v.push_back(18);
	v.push_back(45);
	v.push_back(99);
	v.push_back(4);
	sort(v.begin(),v.end());// 默认排序,从小到大
	for_each(v.begin(),v.end(),Printf());
	cout << endl;

	sort(v.begin(), v.end(), Grater1());// 添加规则
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	//random_shuffle //洗牌 指定范围内的元素随机调整次序

	v.clear();
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	random_shuffle(v.begin(),v.end());  
	// random:随机 shuffle:洗,蒙混 random shuffle:洗牌
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	//merge // 容器元素合并,并存储到另一容器中

	vector<int> v1;
	vector<int> v2;
	for (int i = 1; i < 7; i++)
	{
		v1.push_back(i*34);
	}
	sort(v.begin(), v.end());
	cout << "merge v1:";
	for_each(v1.begin(), v1.end(), Printf());
	cout << endl;
	cout << "merge v:";
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	v2.resize(v.size() + v1.size()); // 切记,要提前开辟空间
	merge(v.begin(),v.end(),v1.begin(),v1.end(),v2.begin());//(b1,e1,b2,e2,b3)
	cout << "merge (b1,e1,b2,e2,b3):";
	for_each(v2.begin(), v2.end(), Printf());
	cout << endl;
	cout << endl;

	//reverse // 反转指定范围的元素

	random_shuffle(v2.begin(),v2.end());// 打乱 v2 中元素
	cout << "reverse(v2.begin(), v2.end());:" << endl;
	for_each(v2.begin(), v2.end(), Printf());
	cout << endl;
	reverse(v2.begin(), v2.end());
	for_each(v2.begin(), v2.end(), Printf());
	cout << endl;
}

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

//  predicate : 谓词
//算法简介:
//
//copy // 容器内指定范围的元素拷贝到另一容器中
//replace(iterator beg, iterator end, oldvalue, newvalue);

//copy(iterator beg, iterator end, iterator dest);
// dest 目标起始迭代器


//replace // 将容器内指定范围的旧元素修改为新元素
//replace(iterator beg, iterator end, oldvalue, newvalue);

//replace_if // 容器内指定范围满足条件的元素替换为新元素
//replace_if(iterator beg, iterator end, _pred, newvalue);


//swap // 互换两个容器的元素
//swap(container c1, container c2);


class Re_LessFive
{
public:
	bool operator()(int a)
	{
		return a < 5;
	}
};
void test4()
{
	vector<int> v;
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	//copy // 容器内指定范围的元素拷贝到另一容器中

	cout << "v = ";
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	cout << "copy v -> v1 = ";
	v1.resize(v.size());//提前开辟 空间
	copy(v.begin(),v.end(),v1.begin());
	for_each(v1.begin(), v1.end(), Printf());
	cout << endl;

	//replace // 将容器内指定范围的旧元素修改为新元素

	cout << "replace 9 为 1 = ";
	replace(v.begin(),v.end(),9,1);//replace:更换
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	//replace_if // 容器内指定范围满足条件的元素替换为新元素

	replace_if(v.begin(), v.end(), Re_LessFive(),999);
	// 将所有小于5 的值替换为 999
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	//swap:互换两个容器的元素

	v.push_back(89);
	cout << "v1 = ";
	for_each(v1.begin(), v1.end(), Printf());
	cout << endl;
	cout << "v = ";
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	swap(v,v1);

	cout << "swap(v1,v) v1 = ";
	for_each(v1.begin(), v1.end(), Printf());
	cout << endl;
	cout << "swap(v1,v) v = ";
	for_each(v.begin(), v.end(), Printf());
	cout << endl;
}

//    六. 常用算术生成算法
//accumulate // 计算容器元素累计总和 accumulate : 累积,堆积
//accumulate(iterator beg, iterator end, value);
// 计算容器元素累计总和
// value 起始值

//fill // 向容器中添加元素  fill : 填
//fill(iterator beg, iterator end, value);

//注意: 需包含头文件 numeric      numeric : 数字 
void test5()
{
	vector<int> v;
	for (int i = 1; i < 10; i++)
	{
		v.push_back(i);
	}

	//accumulate // 计算容器元素累计总和 accumulate : 累积,堆积
	
	cout << "v 元素数值总和  = " << accumulate(v.begin(), v.end(),10000) << endl;
	for_each(v.begin(), v.end(), Printf());
	cout << endl;

	//fill // 向容器中添加元素  fill : 填

	cout << "fill(v.begin(), v.end(), 8899); v = ";
	fill(v.begin(), v.end()-6, 8899);
	for_each(v.begin(), v.end(), Printf());
	cout << endl;
}

//    七.  常用集合算法
//算法简介:
//
//set_intersection // 求两个容器的交集
//set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
 // dest 目标容器开始迭代器
// 注意:两个集合必须是有序序列
//目标容器开辟空间需要从两个容器中取小值
//set_intersection返回值既是交集中最后一个元素的位置

//set_union // 求两个容器的并集
//set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//求并集的两个集合必须的有序序列
//目标容器开辟空间需要两个容器相加
//set_union返回值既是并集中最后一个元素的位置

//set_difference // 求两个容器的差集
//set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//求差集的两个集合必须的有序序列
//目标容器开辟空间需要从两个容器取较大值
//set_difference返回值既是差集中最后一个元素的位置

void test6()
{
	vector<int> v;
	vector<int> v1;
	vector<int> v2;
	for (int i = 1; i < 10; i++)
	{
		v.push_back(i);
	}
	for (int i = 1; i < 10; i++)
	{
		v1.push_back(i*3);
	}
	cout << "v = ";
	for_each(v.begin(), v.end(), Printf());
	cout << endl;
	cout << "v1 = ";
	for_each(v1.begin(), v1.end(), Printf());
	cout << endl;

	//set_intersection // 求两个容器的交集

	// Method one:   
	//Disadvantage:When outputting,the output free space is 0.
	v2.resize(v.size());
	set_intersection(v.begin(), v.end(), v1.begin(), v1.end(), v2.begin());
	cout << "set_intersection v2 = ";
	for_each(v2.begin(), v2.end(), Printf());
	cout << endl;

	//Method two:
	v2.clear();
	v2.resize(v.size());
	vector<int>::iterator 
		it = set_intersection(v.begin(), v.end(), v1.begin(), v1.end(), v2.begin());
	//返回目标容器的最后一个元素的迭代器地址
	cout << "set_intersection v2 = ";
	for_each(v2.begin(), it, Printf());
	cout << endl;

	//set_union // 求两个容器的并集
	
	v2.clear();
	v2.resize(v.size() + v1.size());
	it = set_union(v.begin(),v.end(),v1.begin(),v1.end(),v2.begin());
	//返回目标容器的最后一个元素的迭代器地址
	cout << "set_union: v2 = ";
	for_each(v2.begin(), it, Printf());
	cout << endl;

	//set_difference // 求两个容器的差集

	v2.clear();
	v2.resize(v.size());
	it = set_difference(v.begin(), v.end(), v1.begin(), v1.end(), v2.begin());
	cout << "set_difference: v2 = ";
	for_each(v2.begin(), it, Printf());
	cout << endl;
}
int main() 
{
	test();
	cout <<" --------------------------" << endl;
	test2();
	cout << " --------------------------" << endl;
	test3();
	cout << " --------------------------" << endl;
	test4();
	cout << " --------------------------" << endl;
	test5();
	cout << " --------------------------" << endl;
	test6();
	cout << " --------------------------" << endl;
	system("pause");

	return 0;
}

2.The result of the run :

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值