第 18.4 節

vector 容器

0瀏覽次數0訪問次數--跳出率--平均停留

vector container

Basic concepts of vector

Features:

  • The vector data structure is very similar to an array, also referred to as a single-ended array.

Difference between vector and ordinary arrays:

  • The difference lies in that arrays occupy static memory while vectors can dynamically extend.

Dynamic Extension:

  • Rather than appending a new space after the original, it searches for a larger memory space, then copies the original data to the new space and frees the original space.

Description: 2015-11-10_151152

  • Vector container iterators support random access.

Vector Constructor

Description:

  • Create a vector container

Function prototype:

  • vector<T> v; // Implemented using template implementation class, default constructor
  • vector(v.begin(), v.end()); //Copies elements from the range [begin(), end()) to itself.
  • vector(n, elem); //The constructor copies n elements to itself.
  • vector(const vector &vec); //Copy constructor.

Example:

#include <iostream>
#include <vector>

using namespace std;

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);
}

int main() {

    test01();


    return 0;
}

运行结果:

0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100

Summary: The various construction methods of vectors are not comparable; use flexibly as needed.

vector assignment operation

Description:

  • 给vector容器赋值可以通过多种方式实现,以下是一些常见方法:

1. 使用初始化列表(最直观)

std::vector<int> vec;
vec = {1, 2, 3, 4, 5}; // C++11及以上

2. 使用assign()成员函数

std::vector<int> vec;
vec.assign(5, 10); // 5个元素,值均为10
vec.assign({1, 2, 3}); // 使用初始化列表

// 从另一个vector的迭代器范围赋值
std::vector<int> source = {4, 5, 6};
vec.assign(source.begin(), source.begin() + 2); // 取前两个元素

3. 使用拷贝赋值运算符

std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2;
vec2 = vec1; // vec2成为vec1的副本

4. 使用花括号初始化

std::vector<int> vec{10, 20, 30}; // 直接初始化

5. 填充赋值

std::vector<int> vec(5); // 先创建5个元素的vector
std::fill(vec.begin(), vec.end(), 42); // 全部填充为42

注意事项:

  • 赋值操作会替换vector中的原有内容
  • 使用assign()可以更灵活地控制新内容
  • 从其他容器赋值时,确保迭代器范围有效

根据具体需求选择合适的赋值方式即可。

Function prototype:

  • vector& operator=(const vector &vec);//overload the equality operator
  • assign(beg, end); // Copies the data in the range [beg, end) to itself.
  • assign(n, elem); // Copies n elements to itself.

Example:

#include <iostream>
#include <vector>

using namespace std;

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;
    v2 = v1;
    printVector(v2);

    vector<int>v3;
    v3.assign(v1.begin(), v1.end());
    printVector(v3);

    vector<int>v4;
    v4.assign(10, 100);
    printVector(v4);
}

int main() {

    test01();


    return 0;
}

运行结果:

0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
100 100 100 100 100 100 100 100 100 100

Summary: Vector assignment is quite straightforward, using either operator= or the assign method.

Vector capacity and size

Description:

  • Operations on the capacity and size of vector containers

Function prototype:

  • empty(); //Determine whether the container is empty
  • capacity(); //Capacity of the container
  • size(); // Returns the number of elements in the container
  • resize(int num); //Reassign the container's length to num; if the container lengthens, fill the new positions with default values.

// If the container becomes shorter, elements at the end that exceed the container length are deleted.

  • resize(int num, elem); // Resize the container to length num, filling any new positions with the value of elem if the container expands.

//if the container becomes shorter, elements at the end that exceed the container length are deleted

Example:

#include <iostream>
#include <vector>

using namespace std;

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);
    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);
}

int main() {

    test01();


    return 0;
}

运行结果:

0 1 2 3 4 5 6 7 8 9
v1不为空
v1的容量 = 16
v1的大小 = 10
0 1 2 3 4 5 6 7 8 9 10 10 10 10 10
0 1 2 3 4

Summary:

  • Check if empty --- empty
  • return element count --- size
  • Return the container capacity
  • Resize

vector insertion and deletion

Description:

  • Performing insertion and deletion operations on a vector container
  • Insertion:
    • push_back(): Adds an element to the end of the vector.
    • insert(): Inserts elements at a specified position within the vector.
    • emplace(): Constructs an element directly in the vector at a given position.
  • Deletion:
    • pop_back(): Removes the last element from the vector.
    • erase(): Deletes elements at a specified position or within a range.
    • clear(): Removes all elements from the vector, leaving it empty.

Note: Insertions and deletions in the middle of a vector may cause shifts in elements, affecting performance. For frequent insertions/deletions, consider alternatives like std::list or std::deque. Always ensure iterators remain valid after modifications.

Function prototype:

  • push_back(ele); //insert element ele at the tail
  • pop_back(); //delete the last element
  • insert(const_iterator pos, ele); // Insert element ele at position pos using the iterator
  • insert(const_iterator pos, int count,ele);//Inserts count elements at the iterator position pos with value ele
  • erase(const_iterator pos); // Delete the element pointed to by the iterator
  • erase(const_iterator start, const_iterator end);//Delete elements between start and end iterators
  • clear(); //Remove all elements from the container

Example:

#include <iostream>

using namespace std;

#include <vector>

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;
    //尾插
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    printVector(v1);
    //尾删
    v1.pop_back();
    printVector(v1);
    //插入
    v1.insert(v1.begin(), 100);
    printVector(v1);

    v1.insert(v1.begin(), 2, 1000);
    printVector(v1);

    //删除
    v1.erase(v1.begin());
    printVector(v1);

    //清空
    v1.erase(v1.begin(), v1.end());
    v1.clear();
    printVector(v1);
}

int main() {

    test01();


    return 0;
}

运行结果:

10 20 30 40 50
10 20 30 40
100 10 20 30 40
1000 1000 100 10 20 30 40
1000 100 10 20 30 40

Summary:

  • Tail insertion --- push_back
  • Pop back --- pop_back
  • Insert --- insert (position iterator)
  • Erase --- erase (position iterator)
  • clear

vector data access

Description:

  • Access and modification operations on data in a vector

Function prototype:

  • at(int idx); // Returns the data pointed to by index idx
  • operator[]; // Returns the data pointed to by index idx
  • front(); // Return the first data element in the container
  • back(); //returns the last data element in the container

Example:

#include <iostream>
#include <vector>

using namespace std;

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

int main() {
    // 程序从 main 函数开始执行,下面的语句会按顺序运行。

    test01();


    // 返回 0 表示程序正常结束。
    return 0;
}

运行结果:

0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
v1的第一个元素为: 0
v1的最后一个元素为: 9

Summary:

  • Apart from using iterators to access elements in a vector container, and at can also be used.
  • The front returns the first element of the container.
  • back returns the last element of the container.

Swap vectors

Description:

  • Implement swapping elements between two containers.

Function prototype:

  • swap(vec); // Swap elements of vec with itself

Example:

#include <iostream>
#include <vector>

using namespace std;

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;
    for (int i = 10; i > 0; i--)
    {
        v2.push_back(i);
    }
    printVector(v2);

    //互换容器
    cout << "互换后" << endl;
    v1.swap(v2);
    printVector(v1);
    printVector(v2);
}

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

    cout << "v的容量为:" << v.capacity() << endl;
    cout << "v的大小为:" << v.size() << endl;

    v.resize(3);

    cout << "v的容量为:" << v.capacity() << endl;
    cout << "v的大小为:" << v.size() << endl;

    //收缩内存
    vector<int>(v).swap(v); //匿名对象

    cout << "v的容量为:" << v.capacity() << endl;
    cout << "v的大小为:" << v.size() << endl;
}

int main() {

    test01();

    test02();


    return 0;
}

运行结果:

0 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1
互换后
10 9 8 7 6 5 4 3 2 1
0 1 2 3 4 5 6 7 8 9
v的容量为:131072
v的大小为:100000
v的容量为:131072
v的大小为:3
v的容量为:3
v的大小为:3

Summary: The swap function can exchange two containers, effectively allowing you to practically reclaim memory.

vector reserved space

Description:

  • 减少vector在动态扩展容量时的扩展次数。

Function prototype:

  • //The container reserves len elements without initialization, making the reserved positions inaccessible.

Example:

#include <iostream>
#include <vector>

using namespace std;

void test01()
{
    vector<int> v;

    //预留空间
    v.reserve(100000);

    int num = 0;
    int* p = NULL;
    for (int i = 0; i < 100000; i++) {
        v.push_back(i);
        if (p != &v[0]) {
            p = &v[0];
            num++;
        }
    }

    cout << "num:" << num << endl;
}

int main() {

    test01();
    

    return 0;
}

运行结果:

num:1

Summary: If the data volume is large, you can start by using reserve to pre-allocate space.

音乐页