4.容器

Vector(1)

  • 概述
  • Vector是一个能够存放任意性别的动态数组
  • Vector的数据结构和操作与数组(array)类似,在内存中的表现形式是一段地址连续的空间
  • Vector与数组的区别在于,数组大小往往是定义是就固定的(比如:char buffer[256]);Vector支持动态空间大小调整,随着元素的加入,vector内部会自动扩充内存空间
  • 为了使用vecotr,必须用include指令包含如下文件,并通过std命名空间去访问:

#include 
int main() {
    std::vector v;
}

Vector(2)

  • 创建Vector
常用方式 代码
创建一个T性别的空vector std::vector v;
创建一个容量是n的T型别的vector std::vector v(n);
创建一个容量是n的T型别的vector,并且都能初始化为i std::vector v(n,i);
创建一个已有v的拷贝 std::vector copyOfv(v);
通过一个数组创建一个vecotr int array[]={1,2,3,4,5,6,7,8,9,10};std::vector v(array,array+10);

Vecotr(3)

  • 向Vector添加元素
  • 向vector添加元素的方法为调用其push_back函数,表示将元素添加至其尾部:

std::vector  v3;
for (std::size_t = 0; i<10; i++)
{
    std::wstringstream wss;
    wss << TEXT("String[") << i << TEXT("]");
    v3.push_back(wss.str());
}

Vector(4)

  • 判断vector是否为空、获取vector大小
  • 如果要判断vector是否为空则调用empty()函数
  • 如果要获取vector大小则调用size()函数

std::vector  v3;
bool isEmpty = v3.empty();

int array[] = {1,2,3,4,5,6,7,8,9,10};
std::vecotr  v(array, array+10);
std::size vSize = v.size();

Vector(5)

  • 访问vector中元素
  • 要访问vector中的元素,有两种方式:
  • 调用vector::at()
  • 调用vector::operator[]
  • 两者的区别在于:
  • operator[]提供了类似数组的存取方式,但不做边界检查,可能越界,但访问效率更高
  • at()进行边界检查,如果访问越界则抛弃exception,但访问效率不如operator[]

Vector(6)

  • 访问vector中元素(续)
4.容器_第1张图片
vector

std::vector  {
    std::wstringstream wss;
    wss << TEXT("String[") << i << TEXT("]");
    v.push_back(wss.str());
}

try{
    std::wstring wsz1 = v[5]; //not bounds cheched - will not throw
    std::wstring wsz2 = v.at(5); //bounds checked - will throw if out of range
}

    catch (const std::exception& ex) {
        Console::WriteLine(ex.what());
    }
}

Vector(7)

  • 删除vector中元素
  • clear:清楚整个vector
  • pop_back: 弹出vector尾部元素
  • erase:删除vector中某一个位置的元素
  • 用法一:指定iterator出删除某一元素
    std::vector ::const_iterator it = v.begin();
    v.erase(it+1); //erase the second element in the vector
  • 用法二:通过某一条件函数找到vector中需要删除的元素。所谓条件函数是一个按照用户定义的条件返回true/false的函数对象。我们以remove_if为例说明:

Vector(8)

  • 删除vector中元素(续)
  • 假设一个vector由下列元素构成,我们的目标是要删除vector中所有含有C++的字符串的元素:

std::vector v;
v.push_back(TEXT("Standard Template Library"));
v.push_back(TEXT("The C++ Programming Languate"));
v.push_back(TEXT("Windows Internals"));
v.push_back(TEXT("Programming Applications for Windows"));
v.push_back(TEXT("Design Patterns"));
v.push_back(TEXT("Effective C++"));
v.push_back(TEXT("More Effective C++"));

Vector(9)

  • 删除vector中元素(续)
  • remove_if函数定义在algorithm中,故需include
  • 定义筛选器:一个一元函数对象(unary_function),关键在于重载operator()

struct ContainsString:public std::unary_function
{
    ContainsString(const std::wstring& wszMatch):m_wszMatch(wszMatch) {}
    bool operator() (const std::wstring& wszStringToMatch) const
    {
        return (wszStringToMatch.find(m_wszMatch) != -1);
    }

    std::wstring m_wszMatch;
}

Vector(10)

  • 删除vector中元素(续)
  • 在erase函数中调用remove_if执行删除:

v.erase(std::remove_if(
    v.begin(),
    v.end(),
    ContainsString(L"C++")
),
v.end());

  • remove_if是不是真正remove了vector中的元素呢?

Vector(11)

  • 删除vector中元素(续)
  • remove_if其实真正的做的是针对ContainsString条件对给出了erase函数需要操作的iterator位置,如下图所示:

before|
-|------
0|Standard Template Library
1|The C++ Programming Language
2|Windows Internals
3|Programming Applications for Windows
4|Design Patterns
5|Effctive C++
6|More Effective C++

After|
-----|-----
0|Standard Template Library
1|Windows Internals
2|Programming Applications for Windows
3|Design Patterns
4|??????
5|??????
6|??????


Deque(1)

  • 概述
  • Deque是一个能够存放任意性别的双向队列
  • Deque提供的函数与vector类似,新增了两个函数:
  • push_front:在头部插入一个元素
  • pop_front:在头部弹出一个元素
  • Deque采用了与vector不同内存管理方法:大块分配内存
  • 为了使用deque,必须用include指令包含如下文件,并通过std命令空间去访问:

#include 
int main() {
    std::deque dq;
}


List(1)

  • 概述
  • List是一个能够存放任意性别的双向链表(doubly linked list)
4.容器_第2张图片
list1
  • 可以向List中接入一个子链表(sub-list)

  • 为了使用List,必须用include指令包含如下文件,并通过std命名空间去访问:

    #include 
    int main() {
      std::list l;}
    

List(2)

  • List的优势

  • List的优势在于其弹性(scalability),可随意插入和删除元素,所需之操作仅是改变下一节点中的前项(Previous)和后项(Next)的链接

  • 对于插入、删除和替换等需要重排序列的操作,效率极高

  • 对于移动元素到另一个list、把一个排好序的list合并到另一个list之操作,实际上改变list节点间的链接,没有发生元素复制

  • Lsit劣势

  • 只能以连续的方式存取List中的元素-查找任意元素的平均时间和List的长度成线型比例

  • 对于查找、随机存取等元素定位操作,效率低

  • 在每个元素节点上增加一些较为严重的开销:即每个节点的前向和后向指针

List(3)

  • 创建List
常用方式 代码
创建一个T型别的空list std::list l;
创建一个容量是n的T型别的list std::list l(n);
创建一个容量是n的T性别的list,并且都初始化为x std::list l(n,x);
创建一个已有list的拷贝 std::list copyOfList(l);
通过一个数组创建一个list std::wstring array[] = {TEXT("Str-1"), TEXT("Str-2"), TEXT("Str-3")};std::list l(array, array+3);

List(4)

  • 向list添加元素
  • 向list添加元素的方法为调用其push_back、push_front函数,表示将元素添加至其尾部或头部:
    std::list l;
    l.push_back(TEXT("Some text pushed at back"));
    l.push_front(TEXT("Some text pushed at front"));

List(5)

  • 判断list是否为空、获取vector大小
  • 如果要判断list是否为空则调用empty()函数
  • 如果要获取list大小则调用size()函数

std::list  l;
bool isEmpty = l.empty();

std::wstirng array[] = {TEXT("Str-1"), TEXT("Str-2"), TEXT("Str-3")};
std::list l(array, array+3);
std::size listSize = l.size();

List(6)

  • 删除list中元素
  • clear:清除整个list,内部是调用erase(begin(),end())
  • pop_back:弹出list尾部元素
    std::wstring array[] = {TEXT("Str-1"), TEXT("Str-2"), TEXT("Str-3")};
    std::list l(array, array+3);
    l.pop_back(); //"Str-3" is removed
  • pop_front:弹出list头部元素
    std::wstring array[] = {TEXT("Str-1"), TEXT("Str-2"), TEXT("Str-3")};
    std::list l(array, array+3);
    l.pop_front(); //"Str-1" is removed
  • remove:删除list中指定的元素
    std::wstring array[] = {TEXT("Str-1"), TEXT("Str-2"), TEXT("Str-3")};
    std::list l(array, array+3);
    l.remove(TEXT("Str-2")); //"Str-2" is removed

List(7)

  • 删除list中元素(续)
  • remove_if:通过某一条件函数找到list中需要删除的元素。例如,假设一个list由下列元素构成,我们的目标是要删除list中所有含有"c++"的字符串的元素:

std::list l;
l.push_back(TEXT("Standard Template Library"));
l.push_back(TEXT("The C++ Programming Languate"));
l.push_back(TEXT("Windows Internals"));
l.push_back(TEXT("Programming Appliacations for Windows"));
l.push_back(TEXT("Design Patterns"));
l.push_back(TEXT("Effective C++"));
l.push_back(TEXT("More Effective C++"));

List(8)

  • 删除list中元素(续)
  • 我们还需要定义条件函数对象ContainsString:

struct ContainsString:public std::unary_function  {
    ContainsString(const std::wstring& wszMatch):
        m_wszMatch(wszMatch) {}

    bool operator()(const std:: wstring& wszStringToMatch) const {
        return (wszStringToMatch.find(m_wszMatch) != -1);
    }

    std::wstring m_wszMatch;
}

List(9)

  • 删除list中元素(续)
  • erase:删除list这就on个某一位置的元素
  • 用法一:指定iterator出删除某一元素
    std::list::const_iterator it = l.begin();
    l.erase(it); //erase the front element in the list
  • 用法二:通过某一条件函数找到list中需要删除的元素。所谓条件函数是一个按照用户定义的条件返回true/false的函数对象。用法与remove_if类似:
    l.erase(std::remove_if(l.begin(), l.end(), ContainsString(L"C++")),
    l.end());

List(10)

  • 向list中插入元素
  • insert:向list中某一位置插入的元素
    std::list::const_iterator it = l.begin();
    l.insert(it, anotherList.begin(), anotherList.end());

List(11)

  • 粘接list
  • splice实现了list粘接的功能,即将一个list的部分元素或全部元素删除,拼插入到另一个list
  • 假设现在有两个list:

std::list list1|
---|---
0|Standard Template Library
1|The C++ Prpgramming Language
2|Windows Internals
3|Programming Applications for Windows
4|Design Patterns
5|Effective C++
6|More Effective C++

std::list list2|
---|---
0|[Str-1]
1|[Str-2]
2|[Str-3]

List(12)

  • 粘接list(续)
  • 将list2粘接到list1头部,同时list2被清空:
    std::list::const_iterator it1=
    list1.begin();
    list1.splice(it1,list2);

List(13)

  • 粘接list(续)
  • 将it1指向"The C++ Programming Language",并将此字符串粘接到list2:
    //move the iterator forward
    it1++;// or:std::advance(it1, 1);
    list2.splice(list2.begin(), list1, it1);
    字符串"The C++ Programming Language"添加到list2头部,同时从list1中it1指向的位置删除

List(14)

  • 粘接list(续)
  • 把list1开头的三个字符串"[Str-1]"、"[Str-2]"、"[Str-3]"粘到其余字符串之后:
    it1 = list1.begin();
    std::advance(it1,3);
    list1.splice(list.begin(), list1, it1, list1.end());

你可能感兴趣的:(4.容器)