STL中的vector 和list

Posted 司马_羽鹤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL中的vector 和list相关的知识,希望对你有一定的参考价值。

参考书目:visual c++ 入门经典 第七版 Ivor Horton著 第十章

认识两个容器:vector和list

容器:是STL(Standard Template Library 标准模板库)的六大组件之一。(容器,容器适配器,迭代器,算法,函数对象,函数适配器)

容器是用来存储和组织其他对象的对象。提供要存储的对象的类型就可以从STL模板中创建容器类。

Vector <T>:表示一个在必要时刻可增加容量的数组,该数组存储T类型的元素。只能在矢量容器的末尾添加新元素。

Vector <int> mydata ;//创建一个存储int 类型的值的容器,存储元素的初始容量是0;

mydata.push_back(99);//向矢量末尾添加一个新元素;

mydata.pop_back();//删除末尾一个元素

mydata.clear();

mydata.insert(begin(mydata)+1,88);//在第1个元素后面插入新的元素88

vec.insert(begin(vec)+1,3,22);//在第一个元素后面插入3个元素,22,22,22

vec.reserve(datasize);//为容器预留空间

例子:(vector容器的构造和读取)

//Person.h
#pragma once
#include <iostream>
#include<cstring>

class Person
{
public:
    Person();
public:
    ~Person();

private:
    void initName(const char* first, const char* second);
    char* firstname;
    char* secondname;
public:
    void showperson()const;
    Person(char* first, char* second);
    Person(const Person & p);
    Person(Person&& p);
    Person& operator=(const Person& p);
    // move
    Person& operator=(Person&& p);
    bool operator<(const Person& p) const;
};
//Person.cpp
#include "Person.h"

Person::Person()
: firstname(NULL)
, secondname(NULL)
{
}


Person::~Person()
{
}


void Person::initName(const char* first, const char* second)
{
    size_t length{ strlen(first) + 1 };
    firstname = new char[length];
    strcpy_s(firstname, length, first);
    length = strlen(second) + 1;
    secondname = new char[length];
    strcpy_s(secondname, length, second);
}


void Person::showperson()const
{
    std::cout << firstname << "" << secondname << std::endl;
}


Person::Person(char* first, char* second)
{
    initName(first, second);
}


Person::Person(const Person & p)
{
    initName(p.firstname, p.secondname);
}


Person::Person(Person&& p)
{
    firstname = p.firstname;
    secondname = p.secondname;
    //reset rvalue object pointer to prevent deletion
    p.firstname = nullptr;
    p.secondname = nullptr;
}

//copy 
Person& Person::operator=(const Person& p)
{
    //TODO: insert return statement here
    if (&p != this)
    {
        delete[] firstname;
        delete[] secondname;
        initName(p.firstname, p.secondname);
    }
    return *this;
}


// move
Person& Person::operator=(Person&& p)
{
    if (&p != this)
    {
        delete[] firstname;
        delete[] secondname;
        firstname = p.firstname;
        secondname = p.secondname;
        //reset rvalue object pointer to prevent deletion
        p.firstname = nullptr;
        p.secondname = nullptr;
    }
    return *this;
    //TODO: insert return statement here
}


bool Person::operator<(const Person& p) const
{
    int result{ strcmp(secondname, p.secondname) };
    return (result<0||result==0&&strcmp(firstname,p.firstname)<0);
}
//Ex10.02.cpp
//storing objects in a vector 
#include <iostream>
#include<vector>
#include "Person.h"

using std::vector;
using std::cout;
using std::endl;


int main()
{
    vector<Person> people;
    const size_t maxlength{ 50 };
    char firstname[maxlength];
    char secondname[maxlength];
    while (1)
    {
        cout << "enter a first name or press Enter to end: ";
        std::cin.getline(firstname, maxlength, \n);
        if (strlen(firstname) == 0)
        {
            break;
        }
        cout << "enter the second name :";
        std::cin.getline(secondname, maxlength, \n);
        people.emplace_back(Person(firstname, secondname));
    }
    cout << endl;
    auto iter = cbegin(people);
    while (iter != cend(people))
    {
        iter->showperson();
        ++iter;
    }
    char mynamef [50] = { "myfirst" };
    char mynames[50] = { "mysecond" };
    Person insert_t ( mynamef, mynames );

    people.insert(begin(people) + 1, insert_t);
    iter = begin(people)+1;
    iter->showperson();
}

 

List<T>

实现了双向链表,优点是:可以在固定时间内在序列的任意位置插入或删除元素,确定是列表不能根据位置直接访问其元素。

访问元素的方法是,从某个已知位置开始遍历列表中的元素。

创建:std::list<double> values (50,2.728);

插入:values.insert(++begin(values),75);

构建元素:emplace( , );emplace_back( );emplace_front();

访问:for (const auto & s:values){std::cout<<s<<endl;}

例子:

 

//example for list
//get some sentences from keyboard ,then store it in the list
#include <iostream>
#include <list>
#include<string>
#include <functional>

using std::string;
using std::cout;
using std::endl;

void listAll(const std::list<string> & strings)
{
    for (auto & s : strings)
    {
        cout << s << endl;
    }
}
int main()
{
    std::list<string> text;//创建list
    cout << "Enter a few lines of text.just press Enter to end :" << endl;
    string sentence;
    while (getline(std::cin, sentence, \n), !sentence.empty())
    {
        text.push_front(sentence);
    }
    cout << "your text in reverse order:  " << endl;//倒叙输出
    listAll(text);

    text.sort();//排序
    cout << "\nyour text in ascending sequence :" << endl;
    listAll(text);

}

后记:

这两个容器还只停留在能用的阶段,要在程序中理解和体会二者的区别与优劣,并深入学习关于数据结构的知识。
在STL中还有很多容器,暂时用不到,有时间要进行系统学习。

以上是关于STL中的vector 和list的主要内容,如果未能解决你的问题,请参考以下文章

STL中的map,list,vectors常见,常用容器

hdu1276士兵队列训练问题[简单STL list]

STL中vector,list,deque和map的区别

STL中 vector 和 list 一些特性

模拟实现stl中的list

STL中vector,list,deque和map的区别