C++ STL算法篇(一) day17

C++ STL算法篇(一) day17

查找类算法

基本查找

  • find:区间查找
  • find_if:条件查找
  • find_first_of:查找区间第一次出现的值
  • adjacent_find:查找第一次重复的值
  • search:子序列查找
  • search_n:子序列查找出现的次数
#include <iostream>
#include <algorithm>
#include <vector>
class student
{
public:
	student(std::string name = "", int age = 0) :name(name), age(age) {}
	std::string getName() { return name; }
	int getAge() { return age; }

	//重载==符
	bool operator==(const std::string& name)
	{
		return this->name == name;
	}
	//重载==符
	bool operator==(const int& age)
	{
		return this->age == age;
	}
protected:
	std::string name;
	int age;
};
void basicSerch()
{
	//1.find区间查找---------------------------------------------------------------------------
	std::vector<int> vec{ 1,3,4,6,2,8,9,5,2,2,1,1,1};
	auto it = find(vec.begin(), vec.end(), 2);
	//未找到返回的end
	if (it != vec.end())
	{
		std::cout << *it << std::endl;
	}
	//find操作自定义数据类型需要重载==符
	std::vector<student> vec2{ {"小瓜",21},{"大瓜",23},{"傻瓜",22} };
	auto it2 = find(vec2.begin(), vec2.end(), "小瓜");
	if (it2 != vec2.end())
	{
		std::cout << it2->getName() << " " << it2->getAge() << std::endl;
	}
	it2 = find(vec2.begin(), vec2.end(), 23);
	if (it2 != vec2.end())
	{
		std::cout << it2->getName() << " " << it2->getAge() << std::endl;
	}
	//2.find_if条件查找,注意三号参数是个函数指针----------------------------------------------
	it = find_if(vec.begin(), vec.end(), [](int& data) {return data == 2; });
	if (it != vec.end())
	{
		std::cout << *it << std::endl;
	}
	//也可以让用户输入进行查找
	int inData;
	std::cin >> inData;
	it = find_if(vec.begin(), vec.end(), [&](int& data) {return data == inData; });
	if (it != vec.end())
	{
		std::cout << *it << std::endl;
	}
	//用find_if就不需要重载==符号了
	it2 = find_if(vec2.begin(), vec2.end(), [](student& object) {return object.getName() == "小瓜"; });
	if (it2 != vec2.end())
	{
		std::cout << it2->getName() << " " << it2->getAge() << std::endl;
	}

	//3.find_first_of查找第一次出现的值,找到两个容器之间第一个相同的元素----------------------------------------
	int arr[]{ 7,8,3 };
	std::cout << *find_first_of(vec.begin(), vec.end(), arr, arr + 3) << std::endl;
	
	//4.adjacent_find查找第一次相邻元素相同的元素--------------------------------------------------
	std::vector<int> vec3{ 1,23,3,2,3,4,6,5,5,8,9 };
	std::cout << *adjacent_find(vec3.begin(), vec3.end()) << std::endl;

	//5.search区间查找子序列,会返回找子序列的第一个元素地址----------------------------------------
	std::vector<int>vec4{ 5,2,2 };
	auto ifSearch = search(vec.begin(), vec.end(), vec4.begin(), vec4.end());
	if (ifSearch != vec.end())
	{
		std::cout << "searchc查找:" <<  std::endl;
		std::cout << *ifSearch << *(ifSearch + 1) << *(ifSearch + 2) << std::endl;
	}
	else
	{
		std::cout << "未找到" << std::endl;
	}

	//6.search_n查找重复多次的元素,第3个参数是出现次数,第4个参数是查找值---------------------------------------------------------------
	//查找的也是相邻的元素,返回第一个相邻元素的地址,返回的也是找到的元素的第一个地址
	auto iter = search_n(vec.begin(), vec.end(), 2, 2);
	std::cout << *iter << *(iter + 1) << *(iter + 2) << std::endl;

}
int main()
{
	basicSerch();
	return 0;
}
  • 运行结果
    在这里插入图片描述

统计查找

  • count:区间统计
  • count_if:条件统计
  • equal:相等比较
#include <iostream>
#include <algorithm>
#include <vector>
class student{
public:
	student(std::string name = "", int age = 0) :name(name), age(age) {}
	std::string getName() { return name; }
	int getAge() { return age; }

	//重载==符
	bool operator==(const std::string& name)
	{
		return this->name == name;
	}
	//重载==符
	bool operator==(const int& age)
	{
		return this->age == age;
	}
protected:
	std::string name;
	int age;
};

void statisticSearch()
{
	std::vector<student> vec2{ {"小瓜",21},{"大瓜",23},{"傻瓜",22} };
	//1.count统计次数-----------------------------------------------------------------------------
	std::vector<int> vec = { 1,3,4,6,2,8,9,5,2,2,1,1,1 };
	std::cout << count(vec.begin(), vec.end(), 1) << std::endl;
	//2.count_if条件统计--------------------------------------------------------------------------
	std::cout <<"大于8的数字有多少个:" <<
		count_if(vec.begin(), vec.end(), [](int& score) {return score > 8; }) << std::endl;

	std::cout << "大于20岁的有多少个:" <<
		count_if(vec2.begin(), vec2.end(), [](student& object) {return object.getAge() > 20; }) << std::endl;
	//3.equal相等比较-----------------------------------------------------------------------------
	std::vector<int> one = { 1,2,3,1,2 };
	std::vector<int> two = { 1,2,3,1,2 };
	std::cout << std::endl << std::boolalpha <<
		equal(one.begin(), one.end(), two.begin(), two.end()) << std::endl;;
}
int main()
{
	statisticSearch();
	return 0;
}

  • 运行结果
    在这里插入图片描述

有序查找

  • binary_search:二分查找
  • upper_bound:查找最后一个大于查找值
  • lowe_bound:大于等于查找值
  • equal_range:区间比较
#include <iostream>
#include <algorithm>
#include <vector>

void orderedSearch()
{
	//以下算法查找必须是有序序列
	//1.二分查找------------------------------------------------------------------------------------------------------
	std::vector<int> vec = { 1,2,3,4,5,6,7,7,8,9 };
	std::cout << std::boolalpha << binary_search(vec.begin(), vec.end(), 5) << std::endl;

	//2.大于----------------------------------------------------------------------------------------------------------
	std::cout << "大于:" << *upper_bound(vec.begin(), vec.end(), 8) << std::endl;

	//3.大于等于------------------------------------------------------------------------------------------------------
	std::cout << "大于等于:" << *lower_bound(vec.begin(), vec.end(), 8) << std::endl;

	//4,2和3的综合体: equal_range() 返回的是一个数对类型,first是等于 second大于的值--------------------------------------------
	std::cout << "first等于:" << *equal_range(vec.begin(), vec.end(), 8).first << std::endl;
	std::cout << "second大于:" << *equal_range(vec.begin(), vec.end(), 8).second << std::endl;
}

int main()
{
	orderedSearch();
	return 0;
}
  • 运行结果
    在这里插入图片描述

集合算法

  • set_union:并集
  • set_intersetction:交集
  • set_difference:差集
  • set_symmetric_difference:对称差集
#include <iostream>
#include <algorithm>
#include <vector>


void print(std::vector<int>& data)
{
	for (auto v : data)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
}
void setLookup()
{
	std::vector<int> one{ 1,3,4,5 };
	std::vector<int> tow{ 2,4,6,8 };
	std::vector<int> unionSet;
	//这些查找容器内的数据必须是有序的
	//1.并集--------------------------------------------------------------
	std::set_union(one.begin(), one.end(), tow.begin(), tow.end(), std::back_inserter(unionSet));
	print(unionSet);
	//2.交集--------------------------------------------------------------
	std::vector<int> intersection;
	std::set_intersection(one.begin(), one.end(), tow.begin(), tow.end(), std::back_inserter(intersection));
	print(intersection);
	//3.差集---------------------------------------------------------------
	std::vector<int> difference;
	std::set_difference(one.begin(), one.end(), tow.begin(), tow.end(), std::back_inserter(difference));
	print(difference);
	//4.对称差集-----------------------------------------------------------
	std::vector<int> symmetric;
	std::set_symmetric_difference(one.begin(), one.end(), tow.begin(), tow.end(), std::back_inserter(symmetric));
	print(symmetric);
}

int main()
{
	setLookup();
	return 0;
}
  • 运行结果
    在这里插入图片描述

排序和通用类算法

  • sort:排序
  • stable_sort:保持相对顺序排序
  • merge:归并排序
  • inplace_merge:归并排序,直接作用在原容器上
  • nth_element:关键字排序
  • partition:分类处理,把条件下的数据分为两部分
  • stable_partion:保持数据相对顺序,分类处理
  • partial_sort:局部排序
  • partial_sort_copy:局部排序结果放到新容器中
  • random_shuffle:乱序算法
  • reverse:逆序
  • reverse_copy:逆序排序另存一个容器
  • rotate:移动元素到末尾
  • rotate_copy:移动元素到末尾的结果另存
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
#include <ctime>
class student
{
public:
	student(std::string name = "", int age = 0) :name(name), age(age) {}
	std::string getName()const { return name; };
	int getAge()const { return age; };
protected:
	std::string name;
	int age;
};

void universalSort()
{
	//1.sort排序--------------------------------------------------------------------
	std::vector<int> vec1{ 1,2,3,5,7,8,4,6,10,9 };
	//默认less排序
	std::sort(vec1.begin(), vec1.end(), std::less<int>());
	copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;
	//greater排序---------------------------------------------------------------------
	std::sort(vec1.begin(), vec1.end(), std::greater<int>());
	copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;
	//list内置sort算法
	std::list<int> li = { 1,3,5,7,9,2,4,6,8,10 };
	li.sort(std::less<int>());
	copy(li.begin(), li.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;
	//排序自定义类型
	std::vector<student> xiaogua = { {"1小瓜",21},{"3小傻",23},{"2小姐",22} };
	std::sort(xiaogua.begin(), xiaogua.end(), [](const student& one, const student& two)
		{return one.getAge() < two.getAge(); });
	for (auto v : xiaogua)
	{
		std::cout << v.getName() << "\t" << v.getAge() << std::endl;
	}
	std::cout << std::endl;
	std::sort(xiaogua.begin(), xiaogua.end(), [](const student& one, const student& two)
		{return one.getName() < two.getName(); });
	for (auto v : xiaogua)
	{
		std::cout << v.getName() << "\t" << v.getAge() << std::endl;
	}
	
	//2.stable_sort保持相对顺序排序---------------------------------------------------------------------
	std::vector<double> dNum = { 1.11,3.22,3.21,1.23,1.45,4.55,5.43 };
	stable_sort(dNum.begin(), dNum.end(), [](const double& a, const double& b){return int(a) < int(b); });
	std::cout << std::endl;
	copy(dNum.begin(), dNum.end(), std::ostream_iterator<double>(std::cout, " "));
	std::cout << std::endl;

	//3.merge归并排序-------------------------------------------------------------------------
	//必须要是有序序列
	std::vector<int> first = { 1,3,5 };
	std::vector<int> second = { 2,4,6,8 };
	std::vector<int> order;
	merge(first.begin(), first.end(), second.begin(), second.end(), std::back_inserter(order));
	copy(order.begin(), order.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;

	//4.inplace_merge归并结果存储到原容器中-------------------------------------------------------------------
	std::vector<int> value = { 1,3,5,7,9,2,4,6,8,10 };
	inplace_merge(value.begin(), value.begin() + 5, value.end());
	copy(value.begin(), value.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;

	//5.nth_element关键字排序-------------------------------------------------------------------
	std::vector<int> element = { 1,3,5,7,9,2,4,6,8,0 };
	nth_element(element.begin(), element.begin() + 4, element.end());
	copy(element.begin(), element.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;

	//6.partition分类处理:满足条件的放左边-------------------------------------------------------------------
	std::vector<int> e = { 1,3,5,7,9,0,2,4,6,8 };
	partition(e.begin(), e.end(), [](int data) {return data < 6; });
	copy(e.begin(), e.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;
	std::vector<double> dNum1 = { 1.11,3.22,3.21,1.23,1.45,4.55,5.43 };

	//7.stable_partition分类处理保持相对顺序-------------------------------------------------------------------
	stable_partition(dNum1.begin(), dNum1.end(), [](const double& a)
		{return int(a) < 2; });
	std::cout << std::endl;
	copy(dNum1.begin(), dNum1.end(), std::ostream_iterator<double>(std::cout, " "));
	std::cout << std::endl;

	//8.partial_sort局部排序-------------------------------------------------------------------
	std::vector<int> testData = { 88,77,45,18,19,65,34 };
	partial_sort(testData.begin(), testData.begin() + 3, testData.end());
	std::cout << std::endl;
	copy(testData.begin(), testData.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;

	//9.partial_sort_copy局部排序结果另存-------------------------------------------------------------------
	std::vector<int> presult(3);
	partial_sort_copy(testData.begin(), testData.begin() + 3,
		presult.begin(), presult.end());
	std::cout << std::endl;
	copy(presult.begin(), presult.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;

	//10.random_shuffle乱序算法-------------------------------------------------------------------
	//要配合时间种子一起使用就可以达到乱序效果
	std::string str = "XiaoGua";
	random_shuffle(str.begin(), str.end());
	std::cout << str << std::endl;

	//11.reverse反转------------------------------------------------------------------------
	reverse(str.begin(), str.end());
	std::cout << str << std::endl;

	//12.reverse_copy反转结果另存-------------------------------------------------------------------
	std::string strresult;
	reverse_copy(str.begin(), str.end(), std::back_inserter(strresult));
	std::cout << str << std::endl;
	std::cout << strresult << std::endl;

	//13.rotate移动元素到末尾-------------------------------------------------------------------------
	std::string info = { "XiaoGua" };
	rotate(info.begin(), info.begin() + 4, info.end());
	std::cout << info << std::endl;

	//14.rotate_copy移动元素到末尾结果另存-------------------------------------------------------------------
	std::string rotateStr;
	rotate_copy(info.begin(), info.begin() + 4, info.end(), std::back_inserter(rotateStr));
	std::cout << rotateStr << std::endl;
}

int main()
{
	srand((unsigned int)time(NULL));
	universalSort();
	return 0;
}
  • 运行结果
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值