ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++之常用的算法

2022-09-01 18:31:30  阅读:195  来源: 互联网

标签:begin 常用 end int back C++ v1 算法 push


C++之常用的算法

1 函数对象

重载函数调用运算符的类,其对象称为函数对象。 一元仿函数 / 二元仿函数(根据参数个数判定)
class MyPrint {
public:
	void operator() (int num) {
		cout << "num = " << num << endl;
	}
};

void test01() {
	MyPrint myPrint;
	myPrint(2); // 仿函数的调用
}
class MyPrint {
public:
	MyPrint() {
		count = 0;
	}
	void operator() (int num) {
		count++;
		cout << "num = " << num << endl;
		
	}
	int count;
};

// 函数对象超出了普通函数的概念 可以保存状态
void test02() {
	MyPrint myPrint;
	myPrint(1);
	myPrint(10);
	myPrint(10);
	myPrint(10);
	myPrint(10);
	cout << "调用函数对象"<< myPrint.count << "次"<<endl;
}
// 函数对象作为参数传递
void doPrint(MyPrint print,int num) {
	print(num);
}
void test03() {
	MyPrint myPrint;
	doPrint(myPrint,19);
}

总结: 函数对象(仿函数)重载了(),所以就像函数的调用。作为类型与模板配合使用。
set<int,myCompare>

2 谓词

普通函数或返回值是bool值的函数对象(operator()),

class Greater20 {
public:
	bool operator()(int val) {
		return val > 20;
	}
};


// 一元谓词
void test01() {
	vector<int>  v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
	v.push_back(50);

	// 查大于20的数
	Greater20 greater20Then;
	vector<int>::iterator pos  = find_if(v.begin(),v.end(), greater20Then);
	if (pos != v.end()) {
		cout << "找到大于20的位置="<< *pos << endl;
	}
	else {
		cout << "未找到" << endl;
	}
}

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

void test02() {

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

	sort(v.begin(),v.end(), MyCompare());
// 匿名函数 lambda表达式 [](){};
	for_each(v.begin(), v.end(), [](int val) {
		cout << val << " ";
	});
	cout << endl;
}

3 内建函数对象的使用

#include <functional>
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <functional>
#include <vector>
#include <algorithm>

void test01() {

	// 取反仿函数 
	// template<class T> T negate<T>
	negate<int> n;
	cout <<n(10) << endl;

	// 加法
	// template<class T> T plus<T>
	plus<int> p;
	cout << p(1, 1) << endl;
}

// template<class T> bool greater<T>
void test02() {

	vector<int> v;
	v.push_back(10);
	v.push_back(11);
	v.push_back(12);
	v.push_back(9);
	v.push_back(6);

	sort(v.begin(),v.end(),greater<int>());

	for (int a : v) {
		cout << a << " ";
	}
}

int main()
{
	test02();
	system("pause");
	return EXIT_SUCCESS;
}

4 适配器

函数适配器

// 第一步 绑定数据
// 第二步 继承类binary_function<参数类型1,参数类型2,返回值类型>
// 第三步 加const修饰 operator()

class MyPrint : public binary_function<int,int,void>
{
public:
	void operator() (int v,int start) const  // 常函数
	{
		cout << "v=" << v << " start=" << start << " v+start=" << v + start << endl;
	}
};

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

	cout << "请输入一个起始值:" << endl;
	int num;
	cin >> num;
    // 引入头文件 functional  algorithm
	 for_each(v.begin(),v.end(), bind2nd(MyPrint(),num));
	//for_each(v.begin(), v.end(), bind1st(MyPrint(), num));
}


class greater5 :public unary_function<int,bool>
{
public :
	bool operator()(int v)  const
	{
		return v > 5;
	}
};
// 取反适配器
void test02() {
	// 一元取反
	vector<int> v;
	for (int i = 0; i < 10;i++) {
		v.push_back(i);
	}

	// 查找大于5的数字
	vector<int>::iterator pos =  find_if(v.begin(),v.end(), not1(greater5())); // 一元取反

	if (pos != v.end()) {
		cout << "找到小于5的数字" << *pos << endl;
	}
}


vector<int>::iterator pos = find_if(v.begin(), v.end(), not1( bind2nd(greater<int>(),5)));
void myPrint(int v,int start) {
	cout << v << " ";
}
// 函数指针适配器
void test03() {
	vector<int> v;
	for (int i = 0; i < 10;i++) {
		v.push_back(i );
	}
	// 将函数指针 适配为函数对象
	for_each(v.begin(),v.end(),bind2nd(ptr_fun(myPrint),5));
	cout << "\n";
}

// 成员函数适配器
class Person {
public:
	Person(string name, int age) {
		this->m_name = name;
		this->m_age = age;
	}
	string m_name;
	int m_age;

};
void myPrintPerson(Person &p) {
	cout << "姓名:" << p.m_name << "\t年龄:" << p.m_age << endl;
}

void test04() {
	vector<Person> v;
	Person p1("张三",13);
	Person p2("李四", 23);
	Person p3("王五", 33);
	Person p4("赵六", 43);

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	for_each(v.begin(),v.end(), myPrintPerson);
}

// 成员函数的适配器
// mem_fun_ref
for_each(v.begin(), v.end(),mem_fun_ref(&Person::showPerson));

5 常用遍历算法

第一个是for_each
使用for_each需要导入模块
两个作用:1.可以保存状态, 2. 可以绑定参数进行输出

struct MyPrint {  // struct内部默认就是public
	void operator()(int v) {
		cout << v << " ";
		m_Count++;
	}
	int m_Count=0;
};
void test01() {
	vector<int> v;
	for (int i = 0; i < 10;i++) {
		v.push_back(i);
	}
	//for_each(v.begin(),v.end(), showV);
	MyPrint print =  for_each(v.begin(), v.end(), MyPrint());
	cout <<  "累计次数="<< print.m_Count << endl;
	cout << endl;
}
transform算法,将指定容器中的元素搬运到另外一个容器中。
void test04() {
	vector<int> v;  // 原容器
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	vector<int> target;
	//target.reserve(v.size());
	target.resize(v.size());
	transform(v.begin(),v.end(),target.begin(), Transform());

	for_each(target.begin(), target.end(), [](int val) {
		cout << val << " ";
	});
}
// transform的第二种用法: 将两个容器元素搬运到目标元素中
class Transform2 {
public:
	int operator()(int val,int val2) {
		return val + val2;
	}
};

void test05() {
	vector<int> v1;
	vector<int> v2;

	for (int i = 0; i < 10;i++) {
		v1.push_back(i+100); // 100 101  102 103
		v2.push_back(i+10); //  10  11   12  13
	}

	vector<int> vtarget;
	vtarget.resize(v1.size());
	transform(v1.begin(),v1.end(),v2.begin(),vtarget.begin(),Transform2());

	for_each(vtarget.begin(), vtarget.end(), [](int val) {
		cout << val << " ";
	});
	cout << endl;
}

6 常用的查找算法

使用find()查找SLT容器中的元素。

void test() {
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	vector<int>::iterator ele = find(v.begin(),v.end(),5);
	if (ele != v.end()) {
		cout << "找到\n";
	}
	else {
		cout << "未找到\n";
	}
}

查找自定义的数据类型

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

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

	vector<int>::iterator ele = find(v.begin(),v.end(),5);
	if (ele != v.end()) {
		cout << "找到\n";
	}
	else {
		cout << "未找到\n";
	}
}

class Person {
public:
	Person(string name, int age) {
		this->m_Name = name;
		this->age = age;
	}

	bool operator==(const Person &p) {
		if (this->m_Name == p.m_Name  && this->age == p.age) {
			return true;
		}
		else {
			return false;
		}
	}

	string m_Name;
	int age;
};


// 使用find函数查找自定义类型数据
void test02() {
	vector<Person> p;

	Person p1("Alice",12);
	Person p2("Bob",21);
	Person p3("Kili",23);

	p.push_back(p1);
	p.push_back(p2);
	p.push_back(p3);

	vector<Person>::iterator pos = find(p.begin(),p.end(),p2);
	if (pos != p.end()) {
		cout << pos->m_Name << " " << pos->age << endl;
	}
	else{
		cout << "没有找到" << endl;
	}
}
int main()
{
	test02();
	system("pause");
	return EXIT_SUCCESS;
}
// 查找指针类型的数据
class MyCompare:public binary_function<Person *, Person *,bool>
{
public:

	bool operator()( Person  * p1, Person * p2) const
	{
		if (p1->m_Name == p2->m_Name && p1->age == p2->age) {
			return true;
		}
		else return false;
	}
};

void test03() {
	vector<Person *> p;

	Person p1("Alice", 12);
	Person p2("Bob", 21);
	Person p3("Kili", 23);

	p.push_back(&p1);
	p.push_back(&p2);
	p.push_back(&p3);
	
	vector<Person *>::iterator  pos = find_if(p.begin(),p.end(), bind2nd(MyCompare(),&p1));

	if (pos != p.end() ) {
		cout << "找到:" <<(*pos)->m_Name<<"->"<<(*pos)->age<<   endl;
	}
	else {
		cout << "未找到" << endl;
	}
}
/*
adjacent_find 算法 查找相邻重复元素
beg 容器开始迭代器
end 容器结束迭代器
_callback  回调函数 或者谓词
*/

void test04()
{
	vector<int> v;
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);
 
	vector<int>::iterator pos =   adjacent_find(v.begin(), v.end());
	if (pos !=v.end()) {
		cout <<  "找到" <<*pos << endl;  // 5
	}
	else {
		cout << "找到相邻的元素" << endl;
	}
}

/*
binary_search 二分查找
*/
void test05()
{
	vector<int> v;
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);

	bool res =  binary_search  (v.begin(), v.end(),5);
	if (res) {
		cout << "找到" << endl;
	}
	else {
		cout << "没找到" << endl;
	}
}







// count 统计元素的个数
// count_if
class Greate4 {
public:
	bool operator()(int val) {
		return val > 4;
	}
};

void test06()
{
	vector<int> v;
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);

	int nums = count(v.begin(),v.end(),5);
	cout << nums << endl;
	int num = count_if(v.begin(),v.end(), Greate4()); // 输出大于4个元素个数
	cout << num << endl;
}

7 常用的排序算法

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>
#include <ctime>
/*
   merge算法: 容器元素合并,将两个容器并存储到另外一个容器中,两个容器元素必须是有序的
*/
void test01() {

	vector<int> v1;
	vector<int> v2;

	for (int i = 0; i < 10;i++) {
		v1.push_back(i);
		v2.push_back(i+ 1);
	}

	vector<int> vTaregt;
	vTaregt.resize(v1.size()+v2.size());
	merge(v1.begin(),v1.end(),v2.begin(),v2.end(),vTaregt.begin());

	for_each(vTaregt.begin(), vTaregt.end(), [](int v) {cout << v << " ";   });

}

/*
sort 算法
*/

void test02() {
	vector<int> v1;

	v1.push_back(2);
	v1.push_back(1);
	v1.push_back(9);
	v1.push_back(3);
	v1.push_back(11);

	sort(v1.begin(),v1.end());
	for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; });
	sort(v1.begin(), v1.end(),greater<int>());
	cout << endl;
	for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; });
}

// random_shuffle(iterator beg,iterator end)算法  洗牌算法
void test03() {
	srand( (unsigned int)time(NULL));
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);

	}
	random_shuffle(v.begin(), v.end());
	for_each(v.begin(), v.end(), [](int v) { cout << v << " "; });
	cout << endl; 

	// reverse 将容器中的元素翻转
	reverse(v.begin(),v.end());
	for_each(v.begin(), v.end(), [](int v) { cout << v << " "; });
	cout << endl;
}

int main()
{
	//test01();
	//test02();
	test03();
	system("pause");
	return EXIT_SUCCESS;
}

合并算法(merge) / 排序算法

8 常用的拷贝和替换算法

//copy 算法 将一个容器中的元素 拷贝到另外一个容器中
void test01() {
	vector<int> v;
	for (int i = 0; i < 10;i++) {
		v.push_back(i);
	}

	vector<int> v1;
	v1.resize(v.size());

	copy(v.begin(),v.end(),v1.begin());
	for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; });
	cout << endl;
}


// replace
// replace_if

void test02() {
	vector<int> v;
	for (int i = 0; i < 4;i++) {
		v.push_back(i);
	}
	// 将容器中的3替换成300
	replace(v.begin(),v.end(),3,300);
	for_each(v.begin(), v.end(), [](int v) { cout << v << " "; });
}

// swap 算法 交换容器中的两个元素
void test03() {

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

	vector<int> v2;
	v2.push_back(10);
	v2.push_back(20);
	v2.push_back(30);
	v2.push_back(40);

	cout << "交换前的数据:" << endl;
	for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; });
	cout << endl;

	cout << "交换后的数据" << endl;
	swap(v1,v2);
	for_each(v1.begin(), v1.end(), [](int v) { cout << v << " "; });
	cout << endl;

	for_each(v2.begin(), v2.end(), [](int v) { cout << v << " "; });
	cout << endl;
}

9 常用的算数生成算法

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <vector>
#include <numeric>
#include <iterator>
 
// accumulate 累加 计算容器元素的累加和
void test01() {
	vector<int> v;
	for (int i = 0; i < 10;i++) {
		v.push_back(i);
	}

	// 计算累计和
	int res = accumulate(v.begin(),v.end(),10);
	cout << res << endl;

}

// fill 向容器中添加元素
void test02() {
	vector <int> v;
	v.resize(10); // 初始化 10个0
	fill(v.begin(),v.end(),1000); // 填充1000

	copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));

}

int main()
{
	test02();
	system("pause");
	return EXIT_SUCCESS;

10 常用的集合算法(一般用不到)

交集、并集、差集

/*
	set_intersection算法,求两个集合的交集
*/
void test01() {

	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10;i++) {
		v1.push_back(i);
		v2.push_back(i + 5);
	}

	vector<int> vTarget;
	vTarget.resize( min(v1.size(),v2.size()) );
	vector<int>::iterator end =  set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin());
	//for_each(vTarget.begin(), vTarget.end(), [](int v) {
	//	cout << v << " ";
	//});
	copy(vTarget.begin(), end, ostream_iterator<int>(cout," ")); // 5 6 7 8 9
}

// 并集 
// set_union
void test02() {
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
		v2.push_back(i + 5);
	}

	vector<int> vTarget;
	vTarget.resize(v1.size()+v2.size());
	vector<int>::iterator end = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	//for_each(vTarget.begin(), vTarget.end(), [](int v) {
	//	cout << v << " ";
	//});
	copy(vTarget.begin(), end, ostream_iterator<int>(cout, " ")); // 0-14
}

// 差集
void test03() {

	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
		v2.push_back(i + 5);
	}

	vector<int> vTarget;
	vTarget.resize(v1.size() + v2.size());
	// v1-v2
	vector<int>::iterator end = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	//for_each(vTarget.begin(), vTarget.end(), [](int v) {
	//	cout << v << " ";
	//});
	copy(vTarget.begin(), end, ostream_iterator<int>(cout, " ")); // 0-14
}

标签:begin,常用,end,int,back,C++,v1,算法,push
来源: https://www.cnblogs.com/lofly/p/16647469.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有