C++ - STL (below)

Table of contents

1. Case 1 - Judges scoring

1.1 Case description

1.2 Implementation steps

Two, stack container (stack container)

2.1 The basic concept of stack

2.2 Common interfaces of stack

Three, queue container (queue container)

3.1 The concept of queue

3.2 Queue common interface

4. list container (chain container)

4.1 The concept of list

4.2 Related syntax of list

4.3 List container sorting case

5. set/multiset container (collection container)

5.1 Basic concept of set container

5.2 set construction and assignment

5.3 The difference between set and multiset

5.4 Set container sorting

Six, pair pair group creation

Seven, map container

7.1 Basic concept of map container

8. Case 2—Employee grouping

8.1 Case description

8.2 Implementation steps

Nine, STL function object

9.1 The concept of function objects

10. Predicate

10.1 Predicate concept

11. Built-in function objects

11.1 Concept

11.2 Arithmetic functors

11.3 Relational functors

11.4 Logical functors 


1. Case 1 - Judges scoring

1.1 Case description

Contestant ABCDE, 10 judges score each contestant separately, remove the highest score, remove the lowest score among the judges, and take the average score.

1.2 Implementation steps

1. Create five players and put them in the vector

2. Traverse the vector container, take out each player, execute the for loop, and save 10 scores in the deque container

3. The sort algorithm sorts the scores in the deque container, removing the highest and lowest scores

4. The deque container is traversed once, and the total score is accumulated

5. Get average score

The example code is as follows:

#include<iostream>
using namespace std;
#include<deque>
#include<string>
#include <vector>
#include <stdlib.h>
#include <ctime>
#include<algorithm>
//案例1:评委打分
//选手ABCDE,10个评委分别对每一名选手打分,去除最高分,去除评委中最低分,取平均分。
class person
{
public:
	person(string name, int score)
	{
		this->m_name = name;
		this->m_score = score;
	}
	string m_name;//选手名字
	int m_score;//选手分数
};
void creatperson(vector<person>& v1)
{
	string nameseed = "ABCDE";
	for (int i = 0; i < 5; i++)
	{
		string name = "选手";
		name += nameseed[i];
		int score = 0;
		person p(name, score);//创建出具体的选手
		v1.push_back(p);//将创建的person对象放到容器中
	}	
}
//打分
void givescore(vector<person>&v1)
{
	for (vector<person>::iterator it = v1.begin(); it != v1.end(); it++)
	{
		//将评委的分数放入到deque容器中
		deque<int>d1;
		for (int i = 0; i < 10; i++)
		{
			int score = (rand() % 41)+60;//得分在60~100
			d1.push_back(score);
		} 
		cout << "选手:" << it->m_name << "  打分:";
		for (deque<int>::iterator dit = d1.begin(); dit != d1.end(); dit++)
		{
			cout << *dit << " ";
		}
		cout << endl;
		//排序
		sort(d1.begin(), d1.end());
		//去掉最高分和最低分
		d1.pop_front();
		d1.pop_back();
		//算平均分
		int sum = 0;
		for (deque<int>::iterator dit = d1.begin(); dit != d1.end(); dit++)
		{
			sum = sum + *dit;//计算总和
		}
		int avg = sum / d1.size();//此处已经去除最高分和最低分,人数已经变为8个人
		//将平均分赋值给选手身上
		it->m_score = avg;//it 是person的指针,*it是person
	}
}
void print(vector<person>&v1)
{
	for (vector<person>::iterator it = v1.begin(); it != v1.end(); it++)
	{
		cout << "姓名:" <<it->m_name << "  平均分:" << it->m_score << endl;
	}
}
int main()
{
	srand((unsigned int)time(NULL));
	//1.创建五名选手
	vector<person>v1;
	creatperson(v1);
	//2.给5名选手打分
	givescore(v1);
	//3.显示最后得分
	print(v1);

	system("pause");
	return 0;
}

Two, stack container (stack container)

2.1 The basic concept of stack

Concept: stack is a first-in last-out data structure, it has only one exit

Only the top element in the stack can be used by the outside world, so the stack does not allow traversal behavior

The entry of data into the stack is called -  stack push

Popping data from the stack is called -   pop out of the stack

2.2 Common interfaces of stack

Function description: Commonly used external interfaces of stack containers

Constructor:

stack<T> stk; //stack is implemented by template class, the default construction form of stack object

stack(const stack &stk); //copy constructor

Assignment operation:

stack& operator=(const stack &stk);//overload equal sign operator

Data access:

push(elem); //Add an element to the top of the stack

pop(); // remove the first element from the top of the stack

top(); // return the top element of the stack

Size operation:
empty(); //judging whether the stack is empty
size(); //returning the size of the stack

Three, queue container (queue container)

3.1 The concept of queue

Concept: Queue is a first-in, first-out data structure with two exits

A queue container allows adding elements from one end and removing elements from the other end.

Only the head and tail of the queue can be used by the outside world, so the queue does not allow traversal behavior .

Entering data in the queue is called - enqueuing push

3.2 Queue common interface

Function description: Commonly used external interfaces of stack containers

Constructor:

queue<T> que; //queue is implemented by template class, the default construction form of queue object

queue( const queue &que); //copy constructor

Assignment operation:

queue& operator=(const queue &que); // overloaded equal operator

Data access:

push(elem); //Add elements to the end of the queue

pop(); //Remove the first element from the head of the queue

back(); // return the last element

front(); // return the first element

Size operation:

empty(); //Check if the stack is empty

size(); // returns the size of the stack

4. list container (chain container)

4.1 The concept of list

Composition of Linked List: A linked list is composed of a series of nodes .

The composition of the node: one is a data field for storing data elements , and the other is a pointer field for storing the address of the next node .

The linked list in STL is a doubly circular linked list.

Since the storage method of the linked list is not a continuous memory space, the selector in the linked list list only supports forward and backward movement, which is a bidirectional iterator

Advantages of lists:

Using dynamic storage allocation, will not cause memory waste and overflow

The linked list is very convenient to perform insertion and deletion operations, just modify the pointer without moving a large number of elements

Disadvantages of lists:

The linked list is flexible, but the space (pointer field) and time (traversal) are extra expensive

List has an important property , the insertion and deletion operations will not invalidate the original list iterator, which is not true in vector.

Summary: List and vector are the two most commonly used containers in STL, each with its own advantages and disadvantages

*** The related syntax and iterators of list are similar to other containers.

4.2 Related syntax of list

The related syntax and iterators of list are similar to other containers

(1) Flipping and sorting of list containers

sort(); //List sorting

reverse(); // reverse linked list

(All containers that do not support random access iterators cannot use standard algorithms. Containers that do not support random access iterators will provide some corresponding algorithms internally)

Here the member function method is used, using v.sort() and v.reverse().

sort() defaults to ascending order . If you want to use descending order, you can insert functions into it, change its sorting rules, and make it descending

bool mycompare(int v1,int v2)

{

        //Descending order: let the first number > the second number

        return v1>v2;
}

Put this function name into sort(mycompare) to achieve descending order .

4.3 List container sorting case

Case description: Sort the custom data types of Person, and the attributes in Person include name, age, and height

Sorting rules: ascending order by age, descending order by height if the age is the same

The following is the example code:

#include<iostream>
using namespace std;
#include<list>
#include<string>
#include<algorithm>
//案例描述: 将Person自定义数据类型进行排序,Person中属性有姓名、年龄、身高排序
//规则: 按照年龄进行升序,如果年龄相同按照身高进行降序
class person
{
public:
	person(string name, int age, int height)
	{
		this->m_name = name;
		this->m_age = age;
		this->m_height = height;
	}
	string m_name;
	int m_age;
	int m_height;
};
//制定排序规则
bool mycompare1(person &p1,person &p2)
{
	//按年龄 升序
	return p1.m_age < p2.m_age;
	//年龄相同 按照身高 降序
	if (p1.m_age == p2.m_age)
	{
		return p1.m_height > p2.m_height;
	}
}
void test01()
{
	list<person>L;
	person p1("刘备",45 ,175);
	person p2("曹操",45 ,180);
	person p3("孙权",30,175);
	person p4("赵云",30 ,185);
	person p5("张飞",35 ,185);
	person p6("关羽",40 ,200);
	L.push_back(p1);
	L.push_back(p2);
	L.push_back(p3);
	L.push_back(p4);
	L.push_back(p5);
	L.push_back(p6);
	//打印输出
	for (list<person>::iterator it = L.begin(); it != L.end(); it++)
	{
		cout << "姓名:" << (*it).m_name << "  年龄:" << (*it).m_age << "  身高:" << (*it).m_height << endl;
	}
	//排序(这里person里有多种参数,需要自定义规则)
	cout << "------------------------------------";
	cout << "排序后:" << endl;
	L.sort(mycompare1);
	for (list<person>::iterator it = L.begin(); it != L.end(); it++)
	{
		cout << "姓名:" << (*it).m_name << "  年龄:" << (*it).m_age << "  身高:" << (*it).m_height << endl;
	}
}
int main()
{
	test01();
	system("pause");
	return 0;
}

In the above case, sorting needs to use functions to formulate sorting rules by yourself. 

5. set/multiset container (collection container)

5.1 Basic concept of set container

Introduction: All elements will be automatically sorted when inserted

Essence:  set/multiset is an associative container, and the underlying structure is implemented with a binary tree

The difference between set and multiset

1. set does not allow duplicate elements in the container
2. multiset allows duplicate elements in the container

5.2 set construction and assignment

Function description: create set container and assign value

Construction:
set<T> st; //default constructor:

set(const set &st); //copy constructor

assignment:

set& operator=(const set &st); //overload equal sign operator

The size and exchange, insertion and deletion, lookup and statistics of set/multiset containers are similar to other containers .

But the set container has its own characteristics :

1. All elements are automatically sorted when inserted

2. The set container does not allow inserting duplicate values ​​(inserting will not report an error but will not succeed)

5.3 The difference between set and multiset

the difference:

Set cannot insert duplicate data, but multiset can.

When set inserts data, it will return the insertion result, indicating whether the insertion is successful.

multiset does not detect data, so duplicate data can be inserted.

5.4 Set container sorting

The default sorting rule of the set container is from small to large, and the functor can be used to change the sorting rule

#include<iostream>
using namespace std;
#include<set>
#include<cstring>
//set容器排序
class mycompare
{
public:
	bool operator()(int a, int b)const//第一个()代表重载的符号,第二个()代表参数列表
	{
		return a > b;
	}
};
void test01()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(30);
	s1.insert(40);
	s1.insert(50);
	s1.insert(20);
	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	//指定排序规则为从大到小
	set<int, mycompare>s2;
	s2.insert(10);
	s2.insert(30);
	s2.insert(40);
	s2.insert(50);
	s2.insert(20);
	for (set<int,mycompare>::iterator it = s2.begin(); it != s2.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
int main()
{
	test01();
	system("pause");
	return 0;
}

Need to add const         after the functor  , otherwise an error will be reported: an expression with type "const mycompare" will lose some const-volatile qualifiers to call "bool mycompare::operator ()(int,int)". After adding const after the functor, no error will be reported.

        In the functor " bool operator()(int a, int b)const ", the first () represents the overloaded symbol, and the second () represents the parameter list

        When storing custom data types in the set container, you must define its sorting method, otherwise the set container cannot run. The following is a demonstration case:

#include<iostream>
using namespace std;
#include<set>
#include<cstring>
//set容器排序,存放自定义数据类型
class person
{
public:
	person(string name, int age)
	{
		this->m_age = age;
		this->m_name = name;
	}
	string m_name;
	int m_age;
};
class compareperson
{
public:
	bool operator()(const person& p1, const person& p2)const//第一个()代表重载的符号,第二个()代表参数列表
	{
		//按照年龄降序
		return p1.m_age > p2.m_age;
	}
};
void test01()
{
	//自定义数据类型需要指定排序规则
	set<person, compareperson>s1;
	person p1("张三", 18);
	person p2("李四", 20);
	person p3("王五", 25);
	person p4("赵六", 22);

	s1.insert(p1);
	s1.insert(p2);
	s1.insert(p3);
	s1.insert(p4);
	for (set<person, compareperson>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << "姓名:" << (*it).m_name << " 年龄:" << (*it).m_age << endl;
	}
}
int main()
{
	test01();
	system("pause");
	return 0;
}

Six, pair pair group creation

Function description: data that appears in pairs, using pairs can return two data

Two ways to create:

pair<type, type> p (value1, value2 );
pair<type, type> p = make_pair( value1, value2);

The following is the demo code:

#include<iostream>
using namespace std;
#include<cstring>
//pair对组的创建
void test01()
{
	//第一种方式
	pair<string, int>p("Tom", 20);
	cout << "姓名:" << p.first << "  年龄:" << p.second << endl;
	//第二种方式
	pair<string, int>p2 = make_pair("Jack", 25);
	cout << "姓名:" << p2.first << "  年龄:" << p2.second << endl;
}
int main()
{
	test01();
	system("pause");
	return 0;
}

Seven, map container

7.1 Basic concept of map container

Introduction:

1. All elements in the map are pairs.

2. The first element in the pair is key (key value), which acts as an index, and the second element is value (real value)

3. All elements will be automatically sorted according to the key value of the element

4. The map/multimap container can only use insert() to insert elements.

Nature:

map/multimap is an associative container, and the underlying structure is implemented with a binary tree

advantage:

The value can be quickly found according to the key value

The difference between map and multimap:

1.   map does not allow duplicate key value elements in the container

2. Multimap allows duplicate key value elements in the container

8. Case 2—Employee grouping

8.1 Case description

        The company recruited 10 employees (ABCDEFGHI) today. After 10 employees enter the company, they need to be assigned to that department. Employee information includes: name and salary, and departments are divided into: planning, art, and research and development. Randomly assign departments and salaries to 10 employees, insert key (department number) value (employee) through multimap, and display employee information by department.

8.2 Implementation steps

1. Create 10 employees and put them in the vector
2. Traverse the vector container, take out each employee, and perform random grouping.
3. After grouping, use the employee's department number as the key, and the specific employee as the value, and put them into the multimap container.
4. Display employee information by department.

The following is the case code:

#include<iostream>
using namespace std;
#include<string>
#include<vector>
#include<map>
class person
{
public:
	person(string name, int wage)
	{
		this->m_name = name;
		this->m_wage = wage;
	}
	string m_name;
	int m_wage;
};
void creatworker(vector<person>&v1)
{
	string nameseed = "ABCDEFGHIJ";
	for (int i = 0; i < 10; i++)
	{
		string name = "员工";
		name += nameseed[i];
		int wage = rand()%89999+10000;
		person p(name, wage);
		v1.push_back(p);
	}
}
void setgroup(vector<person>& v1, multimap<int, person>& m1)
{
	for (vector<person>::iterator it = v1.begin(); it != v1.end(); it++)
	{
		//随机产生部门编号
		int department = (rand() % 3) + 1;
		//key为部门编号,value为具体员工
		m1.insert(make_pair(department, *it));
	}
}
void showwork(multimap<int, person>& m1)
{
	cout << "策划部门" << endl;
	multimap<int, person>::iterator pos = m1.find(1);
	for (pos = m1.find(1); pos != m1.find(2)&& pos != m1.end(); pos++)
	{
		cout << "姓名:" << pos->second.m_name << " 工资:" << pos->second.m_wage << endl;
	}
	cout << "美术部门" << endl;
	for (pos = m1.find(2); pos != m1.find(3)&& pos != m1.end(); pos++)
	{
		cout << "姓名:" << pos->second.m_name << " 工资:" << pos->second.m_wage << endl;
	}
	cout << "研发部门" << endl;
	for (pos = m1.find(3); pos != m1.end(); pos++)
	{
		cout << "姓名:" << pos->second.m_name << " 工资:" << pos->second.m_wage << endl;
	}
}
void test01()
{
	//1.创建员工
	vector<person>v1;
	creatworker(v1);
	//2.员工分组
	multimap<int, person>m1;
	setgroup(v1, m1);
	//3.分组显示员工
	showwork(m1);
}
int main()
{
	srand((unsigned int)time(NULL));
	test01();
	system("pause");
	return 0;
}

Nine, STL function object

9.1 The concept of function objects

Concept:
1. The class that overloads the function call operator , its object is often called a function object

2. When the function object uses the overloaded (), it behaves like a function call, also called a functor

Nature:

A function object (functor) is a class , not a function

Features:

1. When using a function object, it can be called like a normal function, and can have parameters and return values.

2. Function objects go beyond the concept of ordinary functions, function objects can have their own state

3. Function objects can be passed as parameters

10. Predicate

10.1 Predicate concept

Concept:
1. A functor that returns a bool type is called a predicate

2. If operator() accepts one parameter, it is called a unary predicate.

3. If operator() accepts two parameters, it is called a binary predicate

11. Built-in function objects

11.1 Concept

Concept:  STL has some built-in function objects

Classification:

1. Arithmetic functors

2. Relational functors

3. Logical functors

usage:

1. The objects generated by these functors can be used in exactly the same way as ordinary functions.

2. To use the built-in function object, the header file #include<functional> needs to be introduced.

11.2 Arithmetic functors

Function description:

1. Realize four arithmetic operations
2. Among them, negate is a unary operation, and the others are binary operations imitating

Function prototype:
1. template<class T> T plus<T> //additive functor

2. template<class T> T minus<T> //subtraction functor

3. template<class T> T multiplies<T> //multiplication functor

4. template<class T> T divides<T> //division functor

5. template<class T> T modulus<T> //take imitation function

6. template<class T> T negate<T> //Reverse functor

11.3 Relational functors

Function description: Realize relationship comparison

Functor prototype:

template<class T> bool equal_to<T> //equal to
template<class T> bool not_equal to<T> //not equal to
template<class T> bool greater<T> //greater than
template<class T> bool greater_equal<T > //greater than or equal to
template<class T> bool less<T> //less than
template<class T> bool less_equal<T> //less than or equal to

The following is a code that uses the greater " greater than " relational functor to implement sort() descending order:

#include<iostream>
using namespace std;
#include<vector>
#include<functional>
#include<algorithm>
//内建函数对象 关系仿函数
//大于  greater
void test01()
{
	vector<int>v;
	v.push_back(10);
	v.push_back(40);
	v.push_back(30);
	v.push_back(20);
	v.push_back(50);
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	cout << "降序后" << endl;
	//使用内置函数对象 降序
	sort(v.begin(), v.end(), greater<int>());
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
}
int main()
{
	test01();
	system("pause");
	return 0;
}

The result of the operation is as follows:

10 40 30 20 50
descending after
50 40 30 20 10 

11.4 Logical functors 

Function prototype:

template<class T> bool logical_and<T> //logical and

template<class T> bool logical_or<T> //logical or

template<class T> bool logical_not<T>  //逻辑非

#include<iostream>
using namespace std;
#include<vector>
#include<functional>
#include<algorithm>
//逻辑仿函数
//逻辑非 logical_not

void test01()
{
	vector<bool>v;
	v.push_back(true);
	v.push_back(false);
	v.push_back(true);
	v.push_back(true);
	for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	//利用逻辑非 将容器v 转运到容器v2中 并执行取反操作
	vector<bool>v2;
	v2.resize(v.size());//开辟容器大小
	transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());//transform能转运容器中的内容
	for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)
	{
		cout << *it << " ";
	}
}
int main()
{
	test01();
	system("pause");
	return 0;
}

The result of the operation is as follows:

1 0 1 1
0 1 0 0 


summary

In STL containers, vector, list, and map containers are commonly used containers

Guess you like

Origin blog.csdn.net/m0_74893211/article/details/131884030