编程语言
首页 > 编程语言> > C++之常用的算法

C++之常用的算法

作者:互联网

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