C++11 STL中的Vector使用细节

13 篇文章 0 订阅
2 篇文章 0 订阅

容器

在这里插入图片描述

支持泛型

    vector<int> vi;
    vector<double> vd;
    vector<string> vs;
    list<int> li;
    list<double> ld;
    list<string> ls;
    map<int,string> mis;
    map<string,int> msi;
STL容器优劣对比:
---------------------------------------------------------------------------------
| 容器类型          | 优点                                           | 缺点                                           | 适用场景                               |
|-------------------|------------------------------------------------|------------------------------------------------|----------------------------------------|
| `std::vector`     | 1. 随机访问速度快,O(1)                         | 1. 在中间插入/删除元素慢,O(n)                 | 1. 需要频繁随机访问元素的场景          |
|                   | 2. 在末尾插入/删除元素快,O(1)(平均情况)      | 2. 内存分配可能不连续,导致缓存不友好          | 2. 元素数量变化不大的场景              |
| `std::list`       | 1. 在任意位置插入/删除元素快,O(1)              | 1. 随机访问慢,O(n)                            | 1. 需要频繁在中间插入/删除元素的场景   |
|                   | 2. 内存分配连续,缓存友好                       | 2. 存储开销大,每个元素需要额外存储指针        |                                        |
| `std::deque`      | 1. 随机访问速度快,O(1)                         | 1. 在中间插入/删除元素慢,O(n)                 | 1. 需要频繁在两端插入/删除元素的场景   |
|                   | 2. 在两端插入/删除元素快,O(1)                  | 2. 内存分配可能不连续,导致缓存不友好          |                                        |
| `std::set`        | 1. 元素唯一,自动排序                           | 1. 插入/删除/查找元素慢,O(log n)              | 1. 需要元素唯一且有序的场景            |
|                   | 2. 红黑树实现,平衡性好                        | 2. 存储开销大,每个元素需要额外存储指针        |                                        |
| `std::map`        | 1. 键值对存储,键唯一,自动排序                 | 1. 插入/删除/查找元素慢,O(log n)              | 1. 需要键值对存储且键有序的场景        |
|                   | 2. 红黑树实现,平衡性好                        | 2. 存储开销大,每个元素需要额外存储指针        |                                        |
| `std::unordered_set` | 1. 元素唯一,无序                              | 1. 插入/删除/查找元素慢,O(1)(平均情况)      | 1. 需要元素唯一且无序的场景            |
|                   | 2. 哈希表实现,插入/删除/查找快                | 2. 哈希冲突可能导致性能下降                    |                                        |
| `std::unordered_map` | 1. 键值对存储,键唯一,无序                    | 1. 插入/删除/查找元素慢,O(1)(平均情况)      | 1. 需要键值对存储且键无序的场景        |
|                   | 2. 哈希表实现,插入/删除/查找快                | 2. 哈希冲突可能导致性能下降                    |                                        |
---------------------------------------------------------------------------------

Vector

std::vector是一个非常常用的容器,用于存储一组有序的元素。它类似于动态数组,能够自动调整大小,并且提供了许多方便的成员函数来操作和管理这些元素。

头文件:

#include

初始化:

std::vector<int> vec1; // 空vector
std::vector<int> vec2(5); // 包含5个默认初始化的元素
std::vector<int> vec3(5, 10); // 包含5个值为10的元素
std::vector<int> vec4 = {1, 2, 3, 4, 5}; // 使用初始化列表

添加元素:

vec1.push_back(10);
vec1.push_back(20);

访问元素:

可以使用下标运算符[]或at函数来访问元素:

int firstElement = vec1[0]; // 访问第一个元素
int secondElement = vec1.at(1); // 访问第二个元素

获取大小:

使用size函数可以获取vector中元素的数量:

size_t size = vec1.size();

遍历元素:

使用循环来遍历vector中的所有元素:

    for (size_t i = 0; i < vec1.size(); ++i) {
        std::cout << vec1[i] << " ";
    }

    // 或者使用范围for循环(C++11及以上)
    for (int elem : vec1) {
        std::cout << elem << " ";
    }

常用成员函数

    push_back(value): 在末尾添加一个元素。
    pop_back(): 移除末尾的元素。
    at(index): 访问指定位置的元素,带边界检查。
    operator[](index): 访问指定位置的元素,不带边界检查。
    size(): 返回元素的数量。
    empty(): 检查vector是否为空。
    clear(): 清空所有元素。
    begin(): 返回指向第一个元素的迭代器。
    end(): 返回指向最后一个元素之后位置的迭代器。

示例


#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <string>

using namespace std;
class A
{
public:
    A()
    {
        cout<<"无参构造函数"<<this<<endl;
    }
    A(int i):_data(i)
    {
        cout<<"有参构造函数"<<this<<endl;
    }
    A(const A & other)
    {
        cout<<"拷贝构造 "<<this<<" from "<<&other<<endl;
    }
    A& operator=(const A & other)
    {
        cout<<"拷贝赋值 "<<this<<" from "<<&other<<endl;
    }
    A(const A && other)
    {
        cout<<"移动构造 "<<this<<" from "<<&other<<endl;
    }
    A& operator=(const A && other)
    {
        cout<<"移动赋值 "<<this<<" from "<<&other<<endl;
    }

    ~A()
    {
        cout<<"析构函数"<<this<<endl;
    }
private:
    int _data;
};
int main()
{
    vector<A> va;//定义一个vector容器,元素类型为A
    A a;
    va.push_back(a); //调用了 拷贝构造 0x1f6621e1760 from 0x632efff88c
    //存储了a的副本

    va.push_back(A());//有移动构造就优先调用移动构造 调用了 移动构造 0x1c4b9e41760 from 0x8f7edffcac
    return 0;
}

迭代器操作

//todo 迭代器操作
# include <iostream>
# include <vector>
using namespace std;
int main(){
    vector<int> vi;
    vi={1,2,3,4,5};
//    vector<int> ::iterator it;
//    for(it=vi.begin();it!=vi.end();it++){
//        cout<<*it<<" ";
//    }


    //begin和end
    for(auto it=vi.begin();it!=vi.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;

    //rbegin和rend 反向
    for(auto it=vi.rbegin();it!=vi.rend();it++){
        cout<<*it<<" ";
    }
    cout<<endl;

    // cbegin和cend 不可改 const
    for(auto it=vi.cbegin();it!=vi.cend();it++){
        cout<<*it<<" ";
    }
    cout<<endl;

    // crbegin和crend 不可改 且 反向
    for(auto it=vi.crbegin();it!=vi.crend();it++){
        cout<<*it<<" ";
    }
    return 0;
}

插入和删除操作

//todo 插入和删除操作
# include <iostream>
# include <vector>
using namespace std;
int main1(){
    vector<int> vi;
    vi={1,2,3,4,5};
    vi.push_back(6); //在末尾插入元素

    for(auto &i:vi){
        cout << i << " ";
    }
    cout << endl;
    while (!vi.empty()){//empty()检查容器是否为空
        cout << vi.back() << " "; //输出最后一个元素
        vi.pop_back(); //删除最后一个元素
    }
}

int main(){
    vector<int> vi;
    vi={1,2,3,4,5};
    //在开头插入元素
    vi.insert(vi.begin(),1000);
    for(auto &i:vi){
        cout << i << " ";//1000 1 2 3 4 5
    }
    cout << endl;
    //在中间插入元素
    vi.insert(vi.begin()+2,2000);
    for(auto &i:vi) {
        cout << i << " ";//1000 1 2000 2 3 4 5
    }
    cout << endl;
    //在末尾插入元素
    vi.insert(vi.end(),3000);
    for(auto &i:vi) {
        cout << i << " ";//1000 1 2000 2 3 4 5 3000
    }
    cout << endl;

    //插入多个元素
    vi.insert(vi.begin()+2,5,777);
    for(auto &i:vi) {
        cout << i << " ";//1000 1 777 777 777 777 777 2000 2 3 4 5 3000
    }
    cout << endl;


    //插入一个范围
    int arr[]={11,22,33};
    vi.insert(vi.begin(),arr,arr+3);
    for(auto &i:vi) {
        cout << i << " ";//11 22 33 1000 1 777 777 777 777 777 2000 2 3 4 5 3000
    }
    cout << endl;
    //插入一个范围

    vi.insert(vi.begin(), {999,999});
    for(auto &i:vi) {
        cout << i << " ";//999 999 11 22 33 1000 1 777 777 777 777 777 2000 2 3 4 5 3000
    }
    cout << endl;

    //删除元素
    vi.erase(vi.begin(),vi.begin()+2);
    for(auto &i:vi) {
        cout << i << " ";//11 22 33 1000 1 777 777 777 777 777 2000 2 3 4 5 3000
    }
    cout << endl;

    vi.erase(vi.begin()+3);
    for(auto &i:vi) {
        cout << i << " ";//11 22 33 1 777 777 777 777 777 2000 2 3 4 5 3000
    }
    cout << endl;

    //resize 调整容器大小
    //vi.resize(0);//相当于清空容器
    vi.resize(5);//调整容器大小,只剩下前5个元素
    cout<<"resize"<<endl;
    for(auto &i:vi) {
        cout << i << " ";//11 22 33 1 777
    }
    cout << endl;

    vi.resize(10);//调整容器大小 ,扩展到10个元素,补0
    for(auto &i:vi) {
        cout << i << " ";//11 22 33 1 777 0 0 0 0 0
    }
    cout << endl;

    vi.resize(15,4);//调整容器大小 ,扩展到15个元素,补4
    for(auto &i:vi) {
        cout << i << " ";//11 22 33 1 777 0 0 0 0 0 4 4 4 4 4
    }
    cout << endl;

    vi.clear();
    return 0;
}

与find 配合:

int main(){
    vector<int> vi;
    vi={1,2,3,4,5};

    auto itr= find (vi.begin(), vi.end(), 3); //查找元素3的位置
    if(itr!= vi.end()){//如果找到元素3
        cout << "元素的位置为:" << distance(vi.begin(),itr) << endl; //输出元素3的位置
        vi.erase(itr);//删除元素3
    }else{
        cout << "元素不存在" << endl;
    }
    for(auto &i:vi){
        cout << i << " ";//1 2 3 4 5
    }
    return 0;
}

vector 一些复杂操作

//todo vector 一些复杂操作
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;

int main()
{
    // 创建一个存储字符串的向量
    vector<string> sentence;

    // 预留5个元素的容量,避免频繁的内存分配
    sentence.reserve(5);

    // 向向量中添加第一个字符串
    sentence.push_back(string("Hello,"));

    // 使用initializer_list一次性插入多个字符串到向量的末尾
    sentence.insert(sentence.end(), {"how", "are", "you", "?"});

    // 使用copy算法将向量中的内容复制到输出流,以空格分隔
    copy(sentence.cbegin(), sentence.cend(), ostream_iterator<string>(cout, " "));
    cout << endl;//Hello, how are you ?

    // 输出向量的最大容量、当前大小和当前容量
    cout << " max_size(): " << sentence.max_size() << endl; //max_size(): 288230376151711743
    cout << " size(): " << sentence.size() << endl; //size(): 5
    cout << " capacity(): " << sentence.capacity() << endl; //capacity(): 5


    // 交换向量中第二个和第四个元素的位置
    swap(sentence[1], sentence[3]);

    // 在找到"?"的位置前插入"always"
    sentence.insert(find(sentence.begin(), sentence.end(), "?"), "always");

    // 将向量的最后一个元素修改为"!"
    sentence.back() = "!";

    // 再次输出向量中的内容
    copy(sentence.cbegin(), sentence.cend(), ostream_iterator<string>(cout, " "));
    cout << endl;//Hello, you are how always !

    // 输出修改后的向量大小和容量
    cout << " size(): " << sentence.size() << endl;// size(): 6
    cout << " capacity(): " << sentence.capacity() << endl; // capacity(): 10

    // 移除向量的最后两个元素
    sentence.pop_back();
    sentence.pop_back();

    // 释放未使用的容量,使容量等于当前大小
    sentence.shrink_to_fit();

    // 输出最终的向量大小和容量
    cout << " size(): " << sentence.size() << endl; // size(): 4
    cout << " capacity(): " << sentence.capacity() << endl; // capacity(): 4

    return 0;
}

Vector 的内存管理策略

引例:

//todo vector 内存管理
# include <iostream>
# include <vector>
using namespace std;

int main()
{
    vector<int> vi; // 构造一个包含10个元素的vector
    for(int i=0; i<10; i++) {
        vi.push_back(i); // 向vector中添加元素
        cout<<"size:"<<vi.size()<<endl; // 输出当前vector的大小
        cout<<"capacity:"<<vi.capacity()<<endl; // 输出当前vector的容量
    }

    return 0;
}
输出:
size:1
capacity:1
size:2
capacity:2
size:3
capacity:4
size:4
capacity:4
size:5
capacity:8
size:6
capacity:8
size:7
capacity:8
size:8
capacity:8
size:9
capacity:16
size:10
capacity:16

频繁分配内存,导致效率低下。

有必要优化

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

int main()
{
    vector<int> vi; // 构造一个包含10个元素的vector

    vi.reserve(16); // 预留16个元素的容量,避免频繁的内存分配

    for(int i=0; i<10; i++) {
        vi.push_back(i); // 向vector中添加元素
        cout<<"size:"<<vi.size()<<endl; // 输出当前vector的大小
        cout<<"capacity:"<<vi.capacity()<<endl; // 输出当前vector的容量
    }

    vi.shrink_to_fit(); // 释放未使用的容量,使容量等于当前大小


    cout<<"size:"<<vi.size()<<endl; // 输出当前vector的大小
    cout<<"capacity:"<<vi.capacity()<<endl; // 输出当前vector的容量

    return 0;
}
输出:
size:1
capacity:16
size:2
capacity:16
size:3
capacity:16
size:4
capacity:16
size:5
capacity:16
size:6
capacity:16
size:7
capacity:16
size:8
capacity:16
size:9
capacity:16
size:10
capacity:16
size:10
capacity:10

resize: resize变大等价于调用 push_back(),变小等于 pop_back()

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

int main(){

    vector<int> vi={1,2,3,4,5};
    cout<<"size:"<<vi.size()<<endl; // size:5
    cout<<"capacity:"<<vi.capacity()<<endl; // capacity:5

    //resize 变大等价于调用 push_back(),变小等于 pop_back() ,  与reserve不同
    vi.resize(16);
    cout<<"size:"<<vi.size()<<endl; // size:16
    cout<<"capacity:"<<vi.capacity()<<endl; // capacity:16

    vi.resize(3);
    cout<<"size:"<<vi.size()<<endl; // size:3
    cout<<"capacity:"<<vi.capacity()<<endl; // capacity:16

    vi.resize(100);
    vi.shrink_to_fit(); // 释放未使用的容量,使容量等于当前大小

    cout<<"size:"<<vi.size()<<endl; // size:100
    cout<<"capacity:"<<vi.capacity()<<endl; //capacity:100


    return 0;
}

压入对象

  1. :
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
    A()
    {
        cout<<"无参构造函数"<<this<<endl;
    }
    A(int i):_data(i)
    {
        cout<<"有参构造函数"<<this<<endl;
    }
    A(const A & other)
    {
        cout<<"拷贝构造"<<this<<" from "<<&other<<endl;
    }
    A& operator=(const A & other)
    {
        cout<<"拷贝赋值"<<this<<" from "<<&other<<endl;
    }
    ~A()
    {
        cout<<"析构函数"<<this<<endl;
    }
private:
    int _data;
};

int main()
{
    vector<A> va;
    va.reserve(10);
    va.push_back(A()); //拷贝构造0x1e7bc841760 from 0x31467ffcec
    va.resize(2);

    return 0;
}

输出:
无参构造函数0xbb57ffdec
拷贝构造0x169393e1760 from 0xbb57ffdec
析构函数0xbb57ffdec
无参构造函数0x169393e1764
析构函数0x169393e1760
析构函数0x169393e1764

  1. :

int main()
{
    vector<A> va;
    va.reserve(10);
    va.push_back(A()); //拷贝构造0x1e7bc841760 from 0x31467ffcec
    va.resize(3);
    {
        va.resize(2); //本质是pop_back
    }
    cout<<"===";

    return 0;
}


输出:
无参构造函数0x4384bff77c
拷贝构造0x1c74af71760 from 0x4384bff77c
析构函数0x4384bff77c
无参构造函数0x1c74af71764
无参构造函数0x1c74af71768
析构函数0x1c74af71768
===析构函数0x1c74af71760
析构函数0x1c74af71764

  1. :

int main()
{
    vector<A> va;
    A a;
    va.push_back(a);
    va.push_back(a);
    va.push_back(a);
    return 0;
}
构造了7次 ,因为没预留空间 , push_back空间不足 , 会重复申请空间 ,将旧的数据拷贝进新空间 1  2  4  8  16 ...



无参构造函数0x8a77bff9ec
拷贝构造0x24e6e4b1760 from 0x8a77bff9ec
拷贝构造0x24e6e4b1784 from 0x8a77bff9ec
拷贝构造0x24e6e4b1780 from 0x24e6e4b1760
析构函数0x24e6e4b1760
拷贝构造0x24e6e4b1768 from 0x8a77bff9ec
拷贝构造0x24e6e4b1760 from 0x24e6e4b1780
拷贝构造0x24e6e4b1764 from 0x24e6e4b1784
析构函数0x24e6e4b1780
析构函数0x24e6e4b1784
析构函数0x8a77bff9ec
析构函数0x24e6e4b1760
析构函数0x24e6e4b1764
析构函数0x24e6e4b1768
  1. :

int main()
{
    vector<A> va;
    va.reserve(10);//预留空间
    A a;
    va.push_back(a);
    va.push_back(a);
    va.push_back(a);
    return 0;
}

无参构造函数0xa11c9ffb4c
拷贝构造0x2030a9f1760 from 0xa11c9ffb4c
拷贝构造0x2030a9f1764 from 0xa11c9ffb4c
拷贝构造0x2030a9f1768 from 0xa11c9ffb4c
析构函数0xa11c9ffb4c
析构函数0x2030a9f1760
析构函数0x2030a9f1764
析构函数0x2030a9f1768

需要无参构造.

va.resize() 调用的是无参构造函数

当向容器中压的是类对象成员时,最好要保证无参构造器的存在,类似于数组中的类对象一样。
在必要的情况下,要自实现拷贝构造和拷贝赋值。
压入栈中的对象元素在堆中,所申请的内存己托管,无需再次打理。

压入对象指针

容器有内存托管的功能,但仅限于,被压入的实体元素。

若元素为指针类型,则指针被托管。而不是指针所指向的空间被托管。

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

// 定义一个类A,包含构造函数、拷贝构造函数、拷贝赋值运算符和析构函数
class A
{
public:
    // 无参构造函数
    A()
    {
        cout << "无参构造函数 " << this << endl;
    }

    // 有参构造函数,初始化成员变量_data
    A(int i) : _data(i)
    {
        cout << "有参构造函数 " << this << endl;
    }

    // 拷贝构造函数
    A(const A & other)
    {
        cout << "拷贝构造 " << this << " from " << &other << endl;
    }

    // 拷贝赋值运算符
    A& operator=(const A & other)
    {
        cout << "拷贝赋值 " << this << " from " << &other << endl;
        return *this;
    }

    // 析构函数
    ~A()
    {
        cout << "析构函数 " << this << endl;
    }

private:
    int _data; // 私有成员变量
};

int main()
{
    // 动态分配三个A类的对象,使用无参构造函数
    A *p1 = new A;
    A *p2 = new A;
    A *p3 = new A;

    // 创建一个存储A类指针的向量
    vector<A *> vap;

    // 将动态分配的A类对象指针添加到向量中
    vap.push_back(p1);
    vap.push_back(p2);
    vap.push_back(p3);

    // 遍历向量,释放动态分配的A类对象
    for (auto & itr : vap)
        delete itr;

    // 程序结束,返回0
    return 0;
}

输出
无参构造函数 0x28206f61760
无参构造函数 0x28206f61780
无参构造函数 0x28206f61ad0
析构函数 0x28206f61760
析构函数 0x28206f61780
析构函数 0x28206f61ad0

高效插入和删除

尾部的插入和删除是高效的 O(1),其它位置则是低效的 O(n)

故对于 vector 而言,提倡使用 push_back()和 pop_back(),仅量少用 insert 和 erase

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class A
{
public:
    A()
    {
        cout<<"无参构造函数"<<this<<endl;
    }
    A(int i):_data(i)
            {
                    cout<<"有参构造函数"<<this<<endl;
            }
            A(const A & other)
    {
        cout<<"拷贝构造"<<this<<" from "<<&other<<endl;
    }
    A& operator=(const A & other)
    {
        cout<<"拷贝赋值"<<this<<" from "<<&other<<endl;
    }
    ~A()
    {
        cout<<"析构函数"<<this<<endl;
    }
private:
    int _data;
};
int main()
{
    vector<A> va;
    va.reserve(100);
    for(int i=0; i<10; i++)
    {
        va.push_back(A());
    }
    va.insert(va.begin(),100);//在头部插入会带来大量的拷贝

    //如下的插入才是高效的
    va.push_back(A());
    va.insert(va.end(),A());

    va.erase(va.begin());//在头部删除会带来大量的拷贝
    //如下的删除才是高效的
    va.pop_back();
    va.erase(va.end()-1);

    return 0;
}

迭代器失效

迭代器,实际是一个对象,一个智能指针,重载了operator*和operator->;


//在遍历过程中删除元素可能会导致迭代器失效,这是一个潜在的问题,但在本例中由于每次删除后都立即退出循环,所以没有引发问题。在实际开发中,处理这种情况时需要格外小心。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> vi;
    int data[10] = {1,3,5,7,9,2,4,6,8,10};
    vi.assign(data,data+10);

    vector<int>::iterator itr;
    for(itr=vi.begin();itr != vi.end(); ++itr)
    {
        if(*itr%2==0)
            vi.erase(itr);
        else
        {
            cout<<*itr<<endl;
        }
    }
    return 0;
}

vector 是一个顺序容器,在内存中是一块连续的内存,当删除一个元素后,内存
中的数据会发生移动,以保证数据的紧凑。所以删除一个数据后,其他数据的地址发生
了变化,之前获取的迭代器根据原有的信息就访问不到正确的数据。

代码优化:

安全地遍历和修改vector中的元素。

通过assign方法将数组中的数据赋值给向量,然后使用迭代器遍历向量中的每个元素。

如果元素是偶数,则使用erase方法从向量中删除该元素,并更新迭代器到下一个有效位置;

如果元素是奇数,则输出该元素,并手动递增迭代器以处理下一个元素。

这种方式避免了在遍历过程中删除元素导致的迭代器失效问题,确保了程序的稳定性和正确性。

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

int main()
{
    // 创建一个存储整数的向量
    vector<int> vi;

    // 定义一个包含10个整数的数组
    int data[10] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};

    // 使用assign方法将数组中的数据赋值给向量
    // data是数组的首地址,data+10是数组的末尾地址(最后一个元素之后的位置)
    vi.assign(data, data + 10);

    // 定义一个迭代器,用于遍历向量
    vector<int>::iterator itr;

    // 遍历向量中的每个元素
    for (itr = vi.begin(); itr != vi.end(); )
    {
        // 如果当前元素是偶数,则从向量中删除该元素
        // 注意:erase方法会返回下一个有效的迭代器位置,因此需要将返回值赋给itr
        if (*itr % 2 == 0)
            itr = vi.erase(itr);
        else
        {
            // 如果当前元素是奇数,则输出该元素
            cout << *itr << endl;
            // 手动递增迭代器,处理下一个元素
            ++itr;
        }
    }

    // 程序结束,返回0
    return 0;
}


二维及多维空间生成

//todo vector 嵌套
# include <iostream>
# include <vector>
using namespace std;


int main1(){

    vector<int> t(5);
    vector<vector<int>> tt(5,t);

    cout<<tt.size()<<endl; // 5
    cout<<tt[0].size()<<endl; // 5
    cout<<tt[1].size()<<endl; // 5
    cout<<tt[2].size()<<endl; // 5
    cout<<tt[3].size()<<endl; // 5
    cout<<tt[4].size()<<endl; // 5

    for(int i=0;i<5;i++){
        for(int j=0;j<5;j++){
            cout<<(tt[i][j]=100)<<" ";
        }
        cout<<endl;
    }
    return 0;
}

int main(){
    vector<int> t;
    vector<vector<int>> tt(5,t);

    srand(time(NULL));
    for(int i=0;i<5;i++){
        for(int j=0;j<rand()%20;j++){
            tt[i].push_back(rand()%100);
        }
    }
    for(int i=0;i<5;i++){
        for(int j=0;j<tt[i].size();j++){
            cout<<tt[i][j]<<" ";
        }
        cout<<endl;
    }
}

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MarkTop1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值