Article directory
The previous article has already started to involve the container part, and this article continues to supplement the container-related records.
1. Container replenishment
1. Pass in the parameters of the custom type to the container
The more common data type here is that we write a class, which can contain many different parameters, as shown below: There are
two main ways to write different types of parameters to the container: direct writing and writing Input address
The following is written in the way of address:
the final output is as follows:
the source code is as follows:
#include<vector>
#include<string>
#include<iostream>
using namespace std;
//自定义数据类型
class Person
{
public:
Person(string name, int age)
{
mName = name;
mAge = age;
}
public:
string mName;
int mAge;
};
void test01()
{
vector<Person> v;
//创建数据
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
Person p5("eee", 50);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
{
cout << "Name:" << (*it).mName << " Age:" << (*it).mAge << endl;
}
}
void test02()
{
vector<Person*> v;
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
Person p5("eee", 50);
v.push_back(&p1);
v.push_back(&p2);
v.push_back(&p3);
v.push_back(&p4);
v.push_back(&p5);
for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++)
{
Person * p = (*it);
cout << "Name:" << p->mName << " Age:" << (*it)->mAge << endl;
}
}
int main()
{
cout << "下面采用传入对象的方式" << endl;
test01();
cout << "下面采用传入指针的方式" << endl;
test02();
system("pause");
return 0;
}
2. Nesting of containers
The container nesting output is as follows:
the output is as follows:
the code is as follows:
#include<vector>
#include<string>
#include<iostream>
using namespace std;
//容器嵌套容器
void test01()
{
vector<vector<int>>v;
vector<int> v1;
vector<int> v2;
vector<int> v3;
vector<int> v4;
for (int i = 0; i < 4; i++)
{
v1.push_back(i + 1);
v2.push_back(i + 2);
v3.push_back(i + 3);
v4.push_back(i + 4);
}
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
v.push_back(v4);
for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++)
{
for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)
{
cout << *vit << " ";
}
cout << endl;
}
}
int main()
{
test01();
system("pause");
return 0;
}
2. STL commonly used containers
1. string container
String is a string of C++, but it is also a class in essence. Here we need to distinguish between string and char*. The difference between them is listed in the following comparison, as shown below: (essentially a relationship between containment and contained)
- char * is a pointer
- string is a class, which encapsulates char* inside the class, and manages this string, which is a container of char* type.
Moreover, the string class internally encapsulates many member methods, which also have related shadows in the C language, such as finding, copying, deleting, replacing replace, inserting these methods, and string manages the memory allocated by char*, so don't worry about copying The out-of-bounds and value out-of-bounds, etc., are handled by the class internally.
The following uses the string constructor
Some common prototypes are as follows:
string();
//Create an empty string such as: string str;
string(const char* s);
//Initialize with string sstring(const string& str);
//Use a string object to initialize another string objectstring(int n, char c);
// Initialize with n characters c
These four situations correspond to the following samples respectively, and I have attached the output at the same time. The results are as follows: The
test code used above is as follows:
#include<iostream>
#include<string>
using namespace std;
void test01(void)
{
string s1;
cout << "str1 = " << s1 << endl;
const char* str = "hello world";
string s2(str);
cout << "str2 = " << s2 << endl;
string s3(s2);
cout << "str3 = " << s3 << endl;
string s4(10, 'a');
cout << "str4 = " << s4 << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
2. Some operations of string (string assignment, concatenation, search, etc.)
1. Assignment
What is worth noting here is this operation:
string& assign(const char *s);
//Assign the string s to the current stringstring& assign(const char *s, int n);
//Assign the first n characters of the string s to the current stringstring& assign(const string &s);
//Assign the string s to the current stringstring& assign(int n, char c);
// Assign n characters c to the current string
The test sample is as follows:
void test01(void)
{
string str1;
str1.assign("hello c++");
cout << "str1 = " << str1 << endl;
string str2;
str2.assign("hello c++", 5);
cout << "str2 = " << str2 << endl;
string str3;
str3.assign(str3);
cout << "str3 = " << str3 << endl;
string str4;
str4.assign(5, 'x');
cout << "str4 = " << str4 << endl;
}
2. Stitching
The relevant instructions are as follows:
string& operator+=(const char* str);
// Overload += operatorstring& operator+=(const char c);
// Overload += operatorstring& operator+=(const string& str);
// Overload += operatorstring& append(const char *s);
//Connect the string s to the end of the current stringstring& append(const char *s, int n);
//Connect the first n characters of the string s to the end of the current stringstring& append(const string &s);
//同operator+=(const string& str)string& append(const string &s, int pos, int n);
//The n characters starting from pos in the string s are connected to the end of the string
Test sample: (the test sample is consistent with the previous instructions)
void test01(void)
{
string str1 = "a";
str1 += "bbbb";
cout << "str1 = " << str1 << endl;
str1 += ':';
cout << "str1 = " << str1 << endl;
string str2 = "cccc";
str1 += str2;
cout << "str1 = " << str1 << endl;
string str3 = "I";
str3.append(" love ");
str3.append("game abcde", 4);
str3.append(str2, 4, 3); // 从下标4位置开始 ,截取3个字符,拼接到字符串末尾
cout << "str3 = " << str3 << endl;
}
3. Find and replace
The relevant instructions are as follows:
int find(const string& str, int pos = 0) const;
//Find the first occurrence of str, starting from posint find(const char* s, int pos = 0) const;
//Find the first occurrence of s, starting from posint find(const char* s, int pos, int n) const;
//Find the first position of the first n characters of s from pos positionint find(const char c, int pos = 0) const;
//Find the first occurrence of character cint rfind(const string& str, int pos = npos) const;
//Find the last position of str, starting from posint rfind(const char* s, int pos = npos) const;
//Find the last occurrence of s, starting from posint rfind(const char* s, int pos, int n) const;
//Find the last position of the first n characters of s from posint rfind(const char c, int pos = 0) const;
//Find the last occurrence of character cstring& replace(int pos, int n, const string& str);
//Replace n characters starting from pos with the string strstring& replace(int pos, int n,const char* s);
//Replace the n characters starting from pos with the string s
Test sample: the first is to find, the second is to replace
void test01()
{
string str1 = "abcdefgde";
int pos = str1.find("de");
if (pos == -1)
{
cout << "未找到" << endl;
}
else
{
cout << "pos = " << pos << endl;
}
pos = str1.rfind("de");
cout << "pos = " << pos << endl;
}
void test02()
{
string str1 = "abcdefgde";
str1.replace(1, 3, "1111");
cout << "str1 = " << str1 << endl;
}
4. Compare
The function description is as follows: (mainly to compare whether they are equal)
int compare(const string &s) const;
// compare with string sint compare(const char *s) const;
// compare with string s
5. Access
The access rules are as follows:
char& operator[](int n);
//Get characters by []char& at(int n);
/ / Get the character through the at method
6. Insertion and deletion
The instructions for using the function are as follows:
string& insert(int pos, const char* s);
//insert stringstring& insert(int pos, const string& str);
//insert stringstring& insert(int pos, int n, char c);
//Insert n characters c at the specified positionstring& erase(int pos, int n = npos);
//Delete n characters starting from Pos
The usage example is as follows:
void test01()
{
string str = "hello";
str.insert(1, "111");
cout << str << endl;
str.erase(1, 3); //从1号位置开始3个字符
cout << str << endl;
}
7. Substring
The function says the following:
string substr(int pos = 0, int n = npos) const;
//Returns a string consisting of n characters starting from pos
The test sample is as follows:
void test01()
{
string str = "abcdefg";
string subStr = str.substr(1, 3);
cout << "subStr = " << subStr << endl;
string email = "[email protected]";
int pos = email.find("@");
string username = email.substr(0, pos);
cout << "username: " << username << endl;
}
Personally, I feel that this is a bit like python, so it will be very convenient to process strings.
3. Container
1. Basic concepts
The vector data structure is very similar to an array , also known as a single-ended array. The difference is that an array is a static space, while a vector can be dynamically expanded. The dynamic expansion here is not to add a new space after the original space, but to find a larger one. memory space, and then copy the original data to the new space to release the original space.
A container can be represented by the following diagram:
2. The constructor of the container
The constructor of the container is described as follows:
vector<T> v;
//Template implementation class implementation, default constructorvector(v.begin(), v.end());
//Copy the elements in the interval v[begin(), end()) to itself.vector(n, elem);
//The constructor copies n elems to itself.vector(const vector &vec);
// copy constructor.
Here's an example of a construct that looks like this:
void printVector(vector<int>& v) {
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01()
{
vector<int> v1; //无参构造
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
vector<int> v2(v1.begin(), v1.end());
printVector(v2);
vector<int> v3(10, 100);
printVector(v3);
vector<int> v4(v3);
printVector(v4);
}
The result of the operation is as follows:
3. Assignment
Some functions for assigning values to vector are as follows:
vector& operator=(const vector &vec);
// Overload the equals operatorassign(beg, end);
//Assign the copy of the data in the interval [beg, end) to itselfassign(n, elem);
// Assign n elem copies to itself
The operation example is as follows:
void test01()
{
vector<int> v1; //无参构造
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
vector<int>v2;
v2 = v1;
printVector(v2);
vector<int>v3;
v3.assign(v1.begin(), v1.end());
printVector(v3);
vector<int>v4;
v4.assign(10, 100);
printVector(v4);
}
The result of the operation is as follows:
4. Capacity and size
The relevant functions that operate on the capacity and size of vector are as follows:
empty();
// Check if the container is emptycapacity();
//capacity of the containersize();
//returns the number of elements in the containerresize(int num);
//Respecify the length of the container as num, if the container becomes longer, fill the new position with the default value. If the container gets shorter, elements at the end that exceed the length of the container are removed.resize(int num, elem);
//Respecify the length of the container as num. If the container becomes longer, fill the new position with the value of elem. If the container gets shorter, elements at the end that exceed the length of the container are removed
The relevant sample code is as follows:
void test01()
{
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
if (v1.empty())
{
cout << "v1为空" << endl;
}
else
{
cout << "v1不为空" << endl;
cout << "v1的容量 = " << v1.capacity() << endl;
cout << "v1的大小 = " << v1.size() << endl;
}
//resize 重新指定大小 ,若指定的更大,默认用0填充新位置,可以利用重载版本替换默认填充
v1.resize(15, 10);
printVector(v1);
//resize 重新指定大小 ,若指定的更小,超出部分元素被删除
v1.resize(5);
printVector(v1);
}
Running results:
Here is a description of the capacity and size of the container. The following figure illustrates this mechanism well: (Source: C++ vector capacity and size )
That is to say, the capacity is applied dynamically. The size of the capacity is related to the algorithm of our new container, and the size is the number of elements.
5. Insertion and deletion
Some functions for insertion and deletion are as follows:
push_back(ele);
//Insert element ele at the endpop_back();
// delete the last elementinsert(const_iterator pos, ele);
//The iterator points to the position pos to insert the element eleinsert(const_iterator pos, int count,ele);
//The iterator points to position pos and inserts count elements eleerase(const_iterator pos);
// delete the element pointed to by the iteratorerase(const_iterator start, const_iterator end);
//Delete the elements from the iterator from start to endclear();
// delete all elements in the container
A relevant usage example is as follows:
void test01()
{
vector<int> v1;
//尾插
cout << "尾部插入" << endl;
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
printVector(v1);
//尾删
cout << "尾部删除" << endl;
v1.pop_back();
printVector(v1);
//插入
cout << "中间插入" << endl;
v1.insert(v1.begin(), 100);
printVector(v1);
v1.insert(v1.begin(), 2, 1000);
printVector(v1);
//删除
cout << "头部删除" << endl;
v1.erase(v1.begin());
printVector(v1);
//清空
cout << "清空" << endl;
v1.erase(v1.begin(), v1.end());
v1.clear();
printVector(v1);
}
The running results are as follows:
6. Data access
The related functions of data access are as follows:
at(int idx);
//Return the data pointed to by the index idxoperator[];
//Return the data pointed to by the index idxfront();
//returns the first data element in the containerback();
//returns the last data element in the container
An example of usage is as follows:
void test01()
{
vector<int>v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
for (int i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
cout << endl;
for (int i = 0; i < v1.size(); i++)
{
cout << v1.at(i) << " ";
}
cout << endl;
cout << "v1的第一个元素为: " << v1.front() << endl;
cout << "v1的最后一个元素为: " << v1.back() << endl;
}
The final running result is as follows:
7. Interchange
Swapping containers is mainly to realize the exchange of elements in two containers, and the related functions are as follows:
swap(vec);
// swap vec with its own elements
An example of usage is as follows:
void test01()
{
vector<int>v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
vector<int>v2;
for (int i = 10; i > 0; i--)
{
v2.push_back(i);
}
printVector(v2);
//互换容器
cout << "互换后" << endl;
v1.swap(v2);
printVector(v1);
printVector(v2);
}
The running results are as follows: