Table of contents
Two, stack container (stack container)
2.1 The basic concept of stack
2.2 Common interfaces of stack
Three, queue container (queue container)
4. list container (chain container)
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
7.1 Basic concept of map container
9.1 The concept of function objects
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