C++ Improves Programming 5: STL-Common Algorithms

Overview:

  • The algorithm mainly <algorithm> <functional> <numeric>consists of header files.
  • <algorithm>It is the largest of all STL header files, covering comparison, exchange, search, traversal operations, copying, modification, etc.
  • <numeric>It is small in size and includes only a few template functions that perform simple mathematical operations on sequences.
  • <functional>Some template classes are defined to declare function objects.

1. Commonly used traversal algorithms

learning target:

  • Master commonly used traversal algorithms

Algorithm introduction:

  • for_each //Traverse the container
  • transform //Move the container to another container

1.1、for_each

Function description:

  • Implement traversal of containers

Function prototype:

  • for_each(iterator beg, iterator end, _func);

// Traversal algorithm traverses container elements

// beg starts the iterator

// end ends the iterator

// _func function or function object

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

//常用遍历算法for_each

//普通函数
void print01(int val)
{
	cout << val << " ";
}

//仿函数
class print02
{
public:
	void operator()(int val)
	{
		cout << val << " ";
	}
};

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

	for_each(v.begin(), v.end(), print01);//传入普通函数
	cout << endl;

	for_each(v.begin(), v.end(), print02());//传入一个匿名函数对象
	cout << endl;
}

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

Summary : for_each is the most commonly used traversal algorithm in actual development and requires proficiency.

The first two parameters of the for_each function need to specify the range of the iterator. The latter parameter can be a function or a functor, and the function is implemented according to the function content (if it is an ordinary function, you only need to pass in the function name; if it is a functor, you need to pass in anonymous function object)

1.2、tranform

Function description:

  • Move container to another container

Function prototype:

  • transform(iterator beg1, iterator end1, iterator beg2, _func);

//beg1 source container starts iterator

//end1 source container end iterator

//beg2 target container starts iterator

//_func function or function object

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

//常用遍历算法  搬运 transform

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

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

void test01()
{
	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(), MyPrint());
}

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

Summarize:

The first and second parameters of the transform function are the start and end iterators of the source container respectively, the third parameter is the start iterator of the target container, and the fourth parameter is the function or functor that determines the insertion method.

(Note: The target container must open up space in advance before moving)

2. Commonly used search algorithms

learning target:

  • Master common search algorithms

Algorithm introduction:

  • find //find elements
  • find_if //Find elements based on conditions
  • adjacent_find //Find adjacent repeated elements
  • binary_search //Binary search method
  • count //Count the number of elements
  • count_if //Count the number of elements according to conditions

2.1、find

Function description:

  • Find the specified element, find the iterator that returns the specified element, and find the iterator that returns the end iterator end()

Function prototype:

  • find(iterator beg, iterator end, value);

// Search for elements by value. If found, return the specified position iterator. If not found, return the end iterator position.

// beg starts the iterator

// end ends the iterator

// value element to find

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

//常用查找算法
//find

//查找内置数据类型
void test01() {

	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 << "没有找到!" << endl;
	}
	else
	{
		cout << "找到:" << *it << endl;
	}
}

class Person {
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
	//重载==
	bool operator==(const Person& p)
	{
		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
		{
			return true;
		}
		return false;
	}

public:
	string m_Name;
	int m_Age;
};

//查找 自定义数据类型
void test02() {

	vector<Person> v;

	//创建数据
	Person p1("aaa", 10);
	Person p2("bbb", 20);
	Person p3("ccc", 30);
	Person p4("ddd", 40);

	//插入数据
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);

	vector<Person>::iterator it = find(v.begin(), v.end(), p2);
	if (it == v.end())
	{
		cout << "没有找到!" << endl;
	}
	else
	{
		cout << "找到姓名:" << it->m_Name << " 年龄: " << it->m_Age << endl;
	}
}

int main()
{
	//test01();
	test02();
	return 0;
}

Summary: Use find to find the specified element in the container. The return value is an iterator, so an iterator pointer is needed to point to the result.

(Note: When the data is a custom type, the custom data types cannot be compared, and the == sign needs to be overloaded)

2.2、find_if

Function description:

  • Find elements by condition

Function prototype:

  • find_if(iterator beg, iterator end, _Pred);

// Search for elements by value. If found, return the specified position iterator. If not found, return the end iterator position.

// beg starts the iterator

// end ends the iterator

// _Pred function or predicate (returns bool type functor)

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

//常用查找算法  find_if

//内置数据类型
class GreaterFive
{
public:
	bool operator()(int val)
	{
		return val > 5;
	}
};

void test01() {

	vector<int> v;

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

	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());

	if (it == v.end()) {
		cout << "没有找到!" << endl;
	}
	else {
		cout << "找到大于5的数字:" << *it << endl;
	}
}

//自定义数据类型
class Person {
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
public:
	string m_Name;
	int m_Age;
};

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

void test02() {

	vector<Person> v;

	//创建数据
	Person p1("aaa", 10);
	Person p2("bbb", 20);
	Person p3("ccc", 30);
	Person p4("ddd", 40);

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);

	vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20());

	if (it == v.end())
	{
		cout << "没有找到!" << endl;
	}
	else
	{
		cout << "找到姓名:" << it->m_Name << " 年龄: " << it->m_Age << endl;
	}
}

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

Summary: find_if is similar to find, but find directly searches for values, while find_if determines the search conditions through functions or functors.

2.3、adjacent_find

Function description:

  • Find adjacent duplicate elements

Function prototype:

  • adjacent_find(iterator beg, iterator end);

// Find adjacent duplicate elements and return the iterator of the first position of the adjacent element

// beg starts the iterator

// end ends the iterator

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

//常用查找算法  adjacent_find

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

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

	if (it == v.end()) {
		cout << "找不到!" << endl;
	}
	else {
		cout << "找到相邻重复元素为:" << *it << endl;
	}
}

int main()
{
	test01();
	return 0;
}

Summary: If there is an interview question about finding adjacent repeated elements, remember to use the adjacent_find algorithm in STL.

2.4、binary_search

Function description:

  • Find whether the specified element exists

Function prototype:

  • bool binary_search(iterator beg, iterator end, value);

//Find the specified element and return true if found, otherwise false

// Note: Not available in unordered sequences

// beg starts the iterator

// end ends the iterator

// value element to find

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

//常用查找算法 binary_search

void test01()
{
	vector<int>v;

	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	//v.push_back(2); 如果是无序序列,结果未知

	//二分查找  容器中是否有9元素
	//注意:容器必须是有序的升序序列
	bool ret = binary_search(v.begin(), v.end(), 9);
	if (ret)
	{
		cout << "找到了" << endl;
	}
	else
	{
		cout << "未找到" << endl;
	}
}

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

Summary: Although the binary search method is very efficient, the elements in the container to be searched must be in an ordered ascending sequence.

2.5、count

Function description:

  • Number of statistical elements

Function prototype:

  • count(iterator beg, iterator end, value);

// Count the number of occurrences of elements

// beg starts the iterator

// end ends the iterator

// value element of statistics

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

//常用查找算法 count

//内置数据类型
void test01()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(4);
	v.push_back(5);
	v.push_back(3);
	v.push_back(4);
	v.push_back(4);

	int num = count(v.begin(), v.end(), 4);

	cout << "4的个数为: " << num << endl;
}

//自定义数据类型
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;
};

void test02()
{
	vector<Person> v;

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

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);

	Person p("诸葛亮", 35);

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

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

Summary: When counting custom data types, you need to overload operator==

From the definition of count, we know that when we compare custom data, the == sign of count cannot compare the custom data, so we need to overload the == sign in the code to give the conditions for determining that the two are equal.

2.6、count_if

Function description:

  • Count the number of elements according to conditions

Function prototype:

  • count_if(iterator beg, iterator end, _Pred);

// Count the number of occurrences of elements based on conditions

// beg starts the iterator

// end ends the iterator

// _Pred predicate

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

//常用查找算法  count_if

class Greater4
{
public:
	bool operator()(int val)
	{
		return val >= 4;
	}
};

//内置数据类型
void test01()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(4);
	v.push_back(5);
	v.push_back(3);
	v.push_back(4);
	v.push_back(4);

	int num = count_if(v.begin(), v.end(), Greater4());

	cout << "大于等于4的个数为: " << num << endl;
}

//自定义数据类型
class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	string m_Name;
	int m_Age;
};

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

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

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);

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

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

Summary: The difference between count_if and count is that count_if can count data based on the conditions of the predicate, while count can only count based on values.

3. Commonly used sorting algorithms

learning target:

  • Master commonly used sorting algorithms

Algorithm introduction:

  • sort // Sort the elements in the container
  • random_shuffle //Shuffle the elements in the specified range and randomly adjust the order
  • merge //Container elements are merged and stored in another container
  • reverse // Reverse the elements in the specified range

3.1、sort

Function description:

  • Sort elements within a container

Function prototype:

  • sort(iterator beg, iterator end, _Pred);
  • // Search for elements by value. If found, return the specified position iterator. If not found, return the end iterator position.
  • // beg starts the iterator // end ends the iterator
  • // _Pred predicate
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <functional>

//常用排序算法  sort

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

class great
{
public:
	bool operator()(int val1, int val2)
	{
		return val1 > val2;
	}
};

void test01() 
{
	vector<int> v;

	v.push_back(10);
	v.push_back(30);
	v.push_back(50);
	v.push_back(20);
	v.push_back(40);

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

	//从大到小排序
	sort(v.begin(), v.end(), greater<int>());
	for_each(v.begin(), v.end(), myPrint);
	cout << endl;
}

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

Summary: By default, sort sorts in ascending order from small to large. If you want to sort in descending order, you need to add a predicate to set the sorting method.

sort is one of the most commonly used algorithms and requires proficiency

3.2、random_shuffle

Function description:

  • Shuffle the elements in the specified range and randomly adjust the order

Function prototype:

  • random_shuffle(iterator beg, iterator end);
  • // Randomly adjust the order of elements within the specified range
  • // beg starts the iterator
  • // end ends the iterator
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <ctime>

//常用排序算法  random_shuffle

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

void test01()
{
	//随机种子随时间改变
	srand((unsigned int)time(NULL));

	vector<int> v;

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

	//打乱顺序
	random_shuffle(v.begin(), v.end());
	for_each(v.begin(), v.end(), myPrint());
	cout << endl;
}

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

Summary: The random_shuffle shuffling algorithm is more practical. Remember to add a random number seed when using it: srand((usingned int)time(NULL));remember to add the time header file#include <ctime>

3.3、merge

Function description:

  • Two container elements are merged and stored in another container

Function prototype:

  • merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

// Container elements are merged and stored in another container

// Note: The two containers must be ordered

// beg1 container 1 starts iterator

// end1 container 1 end iterator

// beg2 container 2 starts iterator

// end2 container 2 end iterator

// dest target container starts iterator

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

//常用排序算法  merge

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

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> vtarget;

	//目标容器需要提前开辟空间
	vtarget.resize(v1.size() + v2.size());

	//合并  需要两个有序序列
	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin());
	for_each(vtarget.begin(), vtarget.end(), myPrint());
	cout << endl;
}

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

Summarize:

1. The two containers merged by merge must be in order, and the merged container must also be in order.

2. Before merging, sufficient memory space must be allocated to the target container in advance.

3.4、reverse

Function description:

  • Reverse the elements in the container

Function prototype:

  • reverse(iterator beg, iterator end);
  • //Reverse the elements in the specified range
  • // beg starts the iterator
  • // end ends the iterator
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>

//常用排序算法  reverse

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

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

	cout << "反转前: " << endl;
	for_each(v.begin(), v.end(), myPrint());
	cout << endl;

	cout << "反转后: " << endl;

	reverse(v.begin(), v.end());
	for_each(v.begin(), v.end(), myPrint());
	cout << endl;
}

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

Summary : reverse reverses the elements in the interval, which may be involved in interview questions

4. Common copy and replacement algorithms

learning target:

  • Master common copy and replacement algorithms

Algorithm introduction:

  • copy // Copy the specified range of elements in the container to another container
  • replace // Modify the old elements in the specified range in the container to new elements
  • replace_if //Replace the elements in the container that meet the specified range with new elements
  • swap // Swap the elements of two containers

4.1、copy

Function description:

  • Copies the specified range of elements in the container to another container

Function prototype :

  • copy(iterator beg, iterator end, iterator dest);

// Search for elements by value. If found, return the specified position iterator. If not found, return the end iterator position.

// beg starts the iterator

// end ends the iterator

// dest target starting iterator

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

//常用拷贝算法  copy

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

void test01()
{
	vector<int> v1;

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

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

	//拷贝
	copy(v1.begin(), v1.end(), v2.begin());

	for_each(v1.begin(), v1.end(), myPrint());
	cout << endl;
	for_each(v2.begin(), v2.end(), myPrint());
	cout << endl;
}

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

Summary: When copying using the copy algorithm, remember to open up space in the target container in advance.

4.2、replace

Function description:

  • Modify the old elements in the specified range of the container to new elements

Function prototype:

  • replace(iterator beg, iterator end, oldvalue, newvalue);

//Replace old elements in the range with new elements

// beg starts the iterator

// end ends the iterator

// oldvalue old element

// newvalue new element

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

//替换算法  replace

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

void test01()
{
	vector<int> v;

	v.push_back(20);
	v.push_back(30);
	v.push_back(20);
	v.push_back(40);
	v.push_back(50);
	v.push_back(10);
	v.push_back(20);

	cout << "替换前:" << endl;
	for_each(v.begin(), v.end(), myPrint());
	cout << endl;

	//将容器中的20 替换成 2000
	cout << "替换后:" << endl;
	replace(v.begin(), v.end(), 20, 2000);
	for_each(v.begin(), v.end(), myPrint());
	cout << endl;
}

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

Summary : replace will replace elements within the interval that meet the conditions

4.3、replace_if

Function description:

  • Replace the elements that meet the condition in the interval with the specified element

Function prototype:

  • replace_if(iterator beg, iterator end, _pred, newvalue);

//Replace elements according to conditions, and replace elements that meet the conditions with specified elements

// beg starts the iterator

// end ends the iterator

// _pred predicate

// new value replaced new element

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

//常用拷贝和替换算法 replace_if

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

class ReplaceGreater30
{
public:
	bool operator()(int val)
	{
		return val >= 30;
	}
};

void test01()
{
	vector<int> v;

	v.push_back(20);
	v.push_back(30);
	v.push_back(20);
	v.push_back(40);
	v.push_back(50);
	v.push_back(10);
	v.push_back(20);

	cout << "替换前:" << endl;
	for_each(v.begin(), v.end(), myPrint());
	cout << endl;

	//将容器中大于等于的30 替换成 3000
	cout << "替换后:" << endl;
	replace_if(v.begin(), v.end(), ReplaceGreater30(), 3000);
	for_each(v.begin(), v.end(), myPrint());
	cout << endl;
}

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

Summary: replace_if searches according to conditions, and you can use functors to flexibly filter to meet the conditions.

4.4、swap

Function description:

  • Swap the elements of two containers

Function prototype:

  • swap(container c1, container c2); // Swap the elements of two containers // c1 container 1 // c2 container 2
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>

//常用拷贝和替换算法  swap

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

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

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

	cout << "交换前: " << endl;
	for_each(v1.begin(), v1.end(), myPrint());
	cout << endl;
	for_each(v2.begin(), v2.end(), myPrint());
	cout << endl;

	cout << "交换后: " << endl;
	swap(v1, v2);
	for_each(v1.begin(), v1.end(), myPrint());
	cout << endl;
	for_each(v2.begin(), v2.end(), myPrint());
	cout << endl;
}

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

Summary : When swapping containers, pay attention to the fact that the containers exchanged must be of the same type.

5. Commonly used arithmetic generation algorithms

learning target:

  • Master common arithmetic generation algorithms

Notice:

  • The arithmetic generation algorithm is a small algorithm, and the header file included when using it is #include <numeric>

Algorithm introduction:

  • accumulate // Calculate the cumulative sum of container elements
  • fill // Add elements to the container

5.1、accumulate

Function description:

  • Calculate the cumulative sum of container elements in a range

Function prototype:

  • accumulate(iterator beg, iterator end, value);
  • // Calculate the cumulative sum of container elements
  • // beg starts the iterator
  • // end ends the iterator
  • // value starting value (based on the starting value, plus the cumulative sum)
#include <iostream>
using namespace std;
#include <numeric>
#include <vector>

//常用算术生成算法
void test01()
{
	vector<int> v;

	for (int i = 0; i <= 100; i++) 
	{
		v.push_back(i);
	}

	int total = accumulate(v.begin(), v.end(), 0);

	cout << "total = " << total << endl;
}

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

Summary : Pay attention to the header file when using accumulate #include <numeric>. This algorithm is very practical.

It should be noted that the last parameter is the starting value, and the final result is the starting value plus the cumulative sum of the container.

5.2、fill

Function description:

  • Fills the container with the specified elements

Function prototype:

  • fill(iterator beg, iterator end, value);
  • // Fill the container with elements
  • // beg starts the iterator
  • // end ends the iterator
  • // value filled value
#include <iostream>
using namespace std;
#include <numeric>
#include <vector>
#include <algorithm>

//常用算术生成算法  fill

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

void test01()
{

	vector<int> v;
	v.resize(10);

	//填充
	fill(v.begin(), v.end(), 100);

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

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

Summary: Use fill to fill the elements in the container range with specified values.

6. Commonly used set algorithms

learning target:

  • Master common set algorithms

Algorithm introduction:

  • set_intersection // Find the intersection of two containers
  • set_union // Find the union of two containers
  • set_difference // Find the difference between two containers

6.1, set_intersection (intersection)

Function description:

  • Find the intersection of two containers

Function prototype:

  • set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

// Find the intersection of two sets

// Note: The two sets must be ordered sequences

// beg1 container 1 starts iterator

// end1 container 1 end iterator

// beg2 container 2 starts iterator

// end2 container 2 end iterator

// dest target container starts iterator

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

//常用集合算法  set_intersection

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

void test01()
{
	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
	}

	/*v2.push_back(5);
	v2.push_back(8);
	v2.push_back(9);
	v2.push_back(6);
	v2.push_back(10);*/

	vector<int> vTarget;
	//取两个里面较小的值给目标容器开辟空间
	vTarget.resize(min(v1.size(), v2.size()));

	//返回目标容器的最后一个元素的迭代器地址
	vector<int>::iterator itEnd = 
		set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());

	for_each(vTarget.begin(), itEnd, myPrint());
	cout << endl;
}

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

Summarize:

  • The two sets for intersection must be an ordered sequence in ascending order.

  • The target container needs to take the smaller value from the two containers to open up space.

  • The return value of set_intersection is the position of the last element in the intersection

6.2、set_union

Function description:

  • Find the union of two sets

Function prototype:

  • set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

// Find the union of two sets

// Note: The two sets must be ordered sequences

// beg1 container 1 starts iterator

// end1 container 1 end iterator

// beg2 container 2 starts iterator

// end2 container 2 end iterator

// dest target container starts iterator

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

//常用集合算法  set_union

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

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(v1.size() + v2.size());

	//返回目标容器的最后一个元素的迭代器地址
	vector<int>::iterator itEnd =
		set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());

	for_each(vTarget.begin(), itEnd, myPrint());
	cout << endl;
}

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

Summarize:

  • Find the necessary ordered ascending sequence for the union of two sets
  • The target container requires the addition of two containers to open up space.

  • The return value of set_union is the position of the last element in the union

6.3、set_different

Function description:

  • Find the difference between two sets

Function prototype:

  • set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

// Find the difference between two sets

// Note: The two sets must be ordered sequences

// beg1 container 1 starts iterator

// end1 container 1 end iterator

// beg2 container 2 starts iterator

// end2 container 2 end iterator

// dest target container starts iterator

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

//常用集合算法  set_different

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

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(max(v1.size(), v2.size()));

	//返回目标容器的最后一个元素的迭代器地址
	cout << "v1与v2的差集为: " << endl;
	vector<int>::iterator itEnd =
		set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	for_each(vTarget.begin(), itEnd, myPrint());
	cout << endl;


	cout << "v2与v1的差集为: " << endl;
	itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
	for_each(vTarget.begin(), itEnd, myPrint());
	cout << endl;
}

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

Summarize:

  • Find the necessary ordered ascending sequence of the two sets of difference sets
  • The target container needs to take the larger value from the two containers to open up space.

  • The return value of set_difference is the position of the last element in the difference set
  • The order of sets difference sets affects the result

Guess you like

Origin blog.csdn.net/qq_63388834/article/details/134969434