STL之vector

  因为在写一些算法题,一般的在线编译器好像都是用vector作为参数,所以有必要对vector总结一下:

7.3 vector

  vector的本质是一个动态数组(dynamic array),类似于c用malloc分配空间。在<vector>头文件内,vector的定义如下:

namespace std
{
    template <typenameT,typename Allocator = allocator<T>>
    class vector;
}

  注意:第二个模板参数可省略,用默认的内存分配器就好了。

7.3.1 vector的能力

  因为内存是连续分配的,所以提供随机访问的能力,如果在末尾添加或删除元素,则性能相当的好。我想,因该是将类成员的size直接减1(原谅我还看不懂满是宏的源码==)。然而在中间删除或添加则会导致O(n)的操作时间,或者当size满了之后再添加也需要O(n)的时间,所以提前定好容量显得至关重要。

  下面介绍初始化函数:

vector<Elem> c          //空vector
vector<Elem> c(c2)     //构造一个与c2vector的拷贝,包括容量与元素
vector<Elem> c=c2     //同上
vector<Elem> c(rv)    //使用右值来构造(move)
vector<Elem> c=rv    //同上
vector<Elem> c(n)     //用elem的default构造函数来初始化n个elelm,容量大小为n。
vector<Elem> c(n,elem) //elem是类型Elem的一个实例,使用它的拷贝构造函数来初始化n个Elem。
vector<Elem> c(beg,end) //使用[beg,end)之间的迭代器来初始化。
vector<Elem> c(initlist)     //使用初始化列来初始化
vec.~vector()            //析构函数

7.3.2 vector的操作

非易更性操作(Nonmodifying operation)

c.empty()    //bool,是否为空。但用size()==0也许更快
c.size()        //返回大小
c.max_size()    //返回元素个数的最大可能数
c.capacity()        //返回容量
c.reserve(num)    //当且仅当容量不足的时候才扩大
c.shrink_to_fit()    //降低容量
c1==c2        //逐个元素比较大小
c1!=c2        //逐个元素调用!=
c1<c2         //之类的大小比较就不写了

  在这里,非易更性操作指的是调用这些函数之后,原有的指针与迭代器仍然有效。然而这里的坑需要注意的是reserve与shrink_to_fit调用成功后指针与迭代器无效,只是原有的逻辑内容未发生变化。

赋值(assignment)

c=c2        //c2的内容拷贝赋值给c
c=rv        //用右值的内容移动给c(move)
c=initlist        //用初始化列初始化
c.assign(n,elem)    //记住,是从开始复制n个元素。n超过了容量大小会自动适配
c.assign(beg,end)        //[beg,end) 复制范围内的元素
c.assign(inilist)
c1.swap(c2)        //置换c1与c2的数据,然而这里原有的指针迭代器也会被置换。
swap(c1,c2)        //同上

元素访问(Element Access)

c[idx]        //不检查范围
c.at[idx]    //超出范围会抛出异常,安全的做法
c.front()    //返回第一元素,不检查容器是否为空
c.back()     //返回最末元素,不检查容器是否为空

  总结一下:使vector原有的迭代器与指针失效有如下两种情况:

  (1)在索引位置上安插或移除元素

  (2)由容量变化而引起的内存重新分配

迭代器(iterator)

c.begin()
c.end()
c.cbegin()    //常量迭代器
c.cend()
c.rbegin()    //反向迭代器,指向了容器最末尾的元素,++往着首位
c.rend()
c.crbegin()
c.crend()

安插与移除(Inserting and Removing)

c.push_back(Elem)
c.pop_back()        //移除最后一个元素
c.insert(pos,Elem)    //在Iterator pos位置前插入元素
c.insert(pos,n,Elem)    //插入n个元素
c.insert(pos,beg,end)    //在位置pos之前插入[beg,end)个元素
c.insert(pos,initlist)
c.emplace(pos,args...)    //调用Elem的以args为参数的构造函数初始化
c.emplace_back(args...)    //在末尾添加
c.erase(pos)    //删除元素并返回之后的迭代器
c.rease(begin,end)
c.resize(num)    //将元素数量改为num,如果size变大,剩下的调用默认初始化
c.resize(num,Elem)    //不同的是,调用Elem的拷贝
c.clear()        //移除所有元素,清空,但内存仍然保留,不同的size变为0

  需要注意的是emplace与insert不同的是,insert插入的是拷贝,而emplace插入的是以args初始化的元素

7.3.3 将vector当作C-Style Array使用

  可以调用c.data()获得首地址,注意这个首地址不同于迭代器,通常少用。

7.3.4 异常处理(Exception Handling)

  有几种清空C++STL做出保证会抛出异常

1.push_back()时发生异常,元素不会被插入到末尾,即不发生效用
2.如果元素的copy/move未发生异常,则容器的相关操作要么成功要么不发生效用
3.pop_back()不会发生异常
4.swap(),clear()不发生异常
5.如果元素的copy/move未发生异常,则容器的相关操作要么成功要么不发生效用,包括POD(plain old data)简朴的老式数据,如C-struct。

7.3.6 Class vector<bool>

  这是模板特化类,与bool不同的是,这里的bool只占用一个位,而不是一个字节,所以迭代器在这里无效,同时内存空间也是原来的八分之一。

操作 效果
c.flip() 将所有bool元素反相(negate)
c[idx].flip() 将idx所指位置反相
c[idx]=val 将idx位置复制第一bit(0或1)
c[idxl]=c[idx2]  

  这里需要注意的是front与back,at等函数返回的都是引用(reference)

  谈一谈初学c++时遇到的一个坑,考虑如下函数

for(auto i=v.begin(),i!=v.end();i++)
    {
        if(condition)
            {
                v.erase(i);
            }
    }

  错误的原因是删除了之后内存布局有变化,所以迭代器会失效,为nullptr,所以会错误。、

  扩充一下例子:

    vector<int> a{ {1,1,2,3,4,5,1} };
    for (auto i = a.begin(); i != a.end(); i++)
    {
        if(*i == 1)
        {
            i=a.erase(i);
        }
    }
    vector<int> a{ {1,1,2,3,4,5,1} };
    for (auto i = a.begin(); i != a.end(); i++)
    {
        while(*i == 1)
        {
            i=a.erase(i);
            if (i == a.end())
                break;
        }
    }
    vector<int> a{ {1,1,2,3,4,5,1} };
    for (auto i = a.begin(); i != a.end(); i++)
    {
        while(*i == 1)
        {
            i=a.erase(i);
            if (i == a.end())
                break;
        }
        if (i == a.end())
            break;
    }

  只有最后一个才是对的,在自己的机子上调试一下吧。

  ps:在容器中删除相同元素的简单做法:vec.erase(remove(vec.begin(),vec.end(),val),vec.end())。

原文地址:https://www.cnblogs.com/manch1n/p/10317672.html