C++ vector和map 一点笔记

/***********************************************/
vector
vector<T> 容器是包含 T 类型元素的序列容器,不同的是 vector<T> 容器的大小可以自动增长,从而可以包含任意数量的元素;因此类型参数 T 不再需要模板参数 N。只要元素个数超出 vector 当前容量,就会自动分配更多的空间。只能在容器尾部高效地删除或添加元素。
vector<T> 容器可以方便、灵活地代替数组。在大多数时候,都可以用 vector<T> 代替数组存放元素。只要能够意识到,vector<T> 在扩展容量,以 及在序列内部删除或添加元素时会产生一些开销;但大多数情况下,代码不会明显变慢。 为了使用 vector<T> 容器模板,需要在代码中包含头文件 vector。

创建vector<T>容器
std::vector<double> values; 
std::vector<double> values(20);
std::vector<long> numbers(20, 99L);//第二个参数指定了所有元素的初始值
std::vector<unsigned int> primes {2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u};


可以用元素类型相同的容器来初始化 vector<T> 容器
std::array<std :: string, 5> words {"one", "two","three", "four", "five"};
std::vector<std::string> words_copy {std::begin(words) , std::end(words)};

获取大小和容量
std::cout << "The size is " << primes.size() << std::endl;
std::cout << "The capacity is" << primes.capacity() << std::endl;

通过调用 reserve() 来增加容器的容量
values.reserve(20);  //如果当前的容量已经大于或等于 20 个元素,那么这条语句什么也不做。
resize() 可以改变容器大小
values.resize (5);
values.resize (7, 99);//第二个参数指定了元素的初始值

获取、访问元素
std::cout << values[0] << values.front () << values.front () << std::endl; //  front() 和 back() 分別返回序列中第一个和最后一个元素的引用,们可以出现在赋值运算符的左边。

/***********************************************/
map

map 容器有 4 种,每一种都是由类模板定义的。所有类型的 map 容器保存的都是键值对类型的元素。map 容器的元素是 pair<const K,T> 类型的对象,这种对象封装了一个 T 类型的对象和一个与其关联的 K 类型的键。pair 元素中的键是 const,因为修改键会扰乱容器中元素的顺序。每种 map 容器的模板都有不同的特性:
    1、map<K,T>容器,保存的是 pair<const K,T> 类型的元素。pair<const K,T> 封装了一对键对象,键的类型是 K,对象的类型是 T。每个键都是唯一的,所以不允许有重复的键;但可以保存重复的对象,只要它们的键不同。map 容器中的元素都是有序的,元素在容器内的顺序是通过比较键确定的。默认使用 less<K> 对象比较。

    2、multimap<K,T> 容器和 map<K,T> 容器类似, 也会对元素排序。 它的键必须是可比较的, 元素的顺序是通过比较键确定的。 和 map<K,T> 不同的是,multimap<K,T> 允许使用重复的键。因此,一个 multimap 容器可以保存多个具有相同键值的 <const K,T> 元素。

    3、unordered_map<K,T> 中 pair< const K,T>元素的顺序并不是直接由键值确定的,而是由键值的哈希值决定的。哈希值是由一个叫作哈希的过程生成的整数,本章后面会解释这一点。unordered_map<K,T>不允许有重复的键。

    4、unordered_multimap<K,T> 也可以通过键值生成的哈希值来确定对象的位置,但它允许有重复的键。

*multi前缀表明键不必唯一,但如果没有这个前缀,键必须唯一。
*unordered_prefix 前缀表明容器中元素的位置是通过其键值所产生的哈希值来决定的,而不是通过比较键值决定的。如果没有该前缀,那么元素的位置就由比较键值决定。


初始化
std::map<std::string, size_t> people{ {"Ann", 25}, {"Bill", 46},{"Jack", 32},{"Jill", 32} };
查找获取
auto value = people.at("Ann");
插入数据
auto ret_pr = people.insert({ "Fred", 22 });
if (!ret_pr.second)
    std::cout << "insert error" << std::endl;
构造元素
class Name
{
public:
    Name(const std::string& name1, const std::string& name2) : first(name1), second(name2) {}
private:
    std::string first{};
    std::string second{};
};
auto pr = people.emplace (Name { "Dan","Druff"},77);
删除元素
value = people.erase(key)
if(value)
    std::cout << "removed success" << std::endl;

创建元素组合四种方法
std::string s1 {"test"}, s2{"that"};
std::pair<std::string, std::string> my_pair{s1, s2};
std::pair<std::string, std::string> your_pair{std::string {"test"},std::string {"that"}};
std::pair<std::string, std::string> his_pair{"test", std::string {"that"}};
std::pair<std::string, std::string> her_pair{"test", "that"};

auto my_pair = std::make_pair(s1, s2);
auto your_pair = std::make_pair(std::string {"test"},std::string {"that"});
auto his_pair = std::make_pair<std::string, std::string>("test",std::string {"that"});
auto her_pair = std::make_pair<std::string, std::string>("test", "that");
抑或
std::pair<std::string, std:: string> new_pair{my_pair}; // 复制pair对象
std::pair<std::string, std::string>
    old_pair{std::make_pair(std::string{"his"},std::string{"hers"})};


生成 tuple 对象
函数 make_tuple() 可以接受不同类型的任意个数的参数,返回的 tuple 的类型由参数的类型决定
auto my_tuple = std::make_tuple (Name{"Peter","Piper"},42,std::string{"914 626 7890"});

std::tuple<std::string, size_t> my_tl;//Default initialization
std:: tuple<Name, std::string> my_t2 {Name {"Andy", "Capp"},std::string{“Programmer”}};
std::tuple<Name,std::string> copy_my_t2{my_t2}; // Copy constructor
std::tuple<std::string, std::string> my_t3 {"this", "that"};

可以用 pair 对象构造只有两个元素的 tuple 对象
auto the_pair = std::make_pair("these","those");
std::tuple<std::string, std::string> my_t4 {the_pair}; std::tuple<std::string, std::string> my_t5 {std::pair <std::string, std::string > { "this", "that"}};

tuple 对象的成员函数 swap() 可以将它的元素和参数交换。参数的类型必须和 tuple 对象的类型一致。
my_t4.swap (my_t5);

get<>() 可以返回 tuple 中的一个元素
auto my_tuple = std::make_tuple (Name {"Peter","Piper"}, 42, std::string {"914 626 7890"});
std::cout << std::get<0>(my_tuple)<< "age = "<<std::get<1>(my_tuple)<< " tel: " << std::get<2>(my_tuple) << std::endl;
--------------------------------------------------------------
eter Piper age = 42 tel: 914 626 7890

tie<>() 提供了另一种访问 tuple 元素的方式
std::tie(Name name,size_t age,std::string phone) = my_tuple;
或者只取第一和第三个:
std::tie(name, std::ignore,phone) = my_tuple;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
multimap

multimap 容器的成员函数 insert() 可以插入一个或多个元素,而且插入总是成功。
std::multimap<string, string> pets; // Element is pair{pet_type, pet_name}
auto iter = pets.insert (std::pair<string, string>{string{"dog"}, string{"Fang"}});
iter = pets.insert(iter, std::make_pair("dog", "Spot")); // Insert Spot before Fang
pets.insert(std::make_pair("dog", "Rover"));// Inserts Rover after Fang
pets.insert (std::make_pair ("cat", "Korky"));// Inserts Korky before all dogs
pets.insert ({{ "rat", "Roland"}, {"pig", "Pinky" }, {"pig", "Perky"}});//Inserts list elements

在插入具有相同键的元素时,可以使用 multimap 的成员函数 emplace_hint(),可以通过为这个函数提供一个迭代器形式的提示符来控制元素的生成位置
auto iter = pets.emplace("rabbit","Flopsy");
iter = pets.emplace_hint (iter, "rabbit", "Mopsy");// Create preceding "Flopsy" 

访问给定键对应的所有元素
auto pr = people.equal_range("Ann");
if(pr.first != std::end(people))
{
    for (auto iter = pr.first ; iter != pr.second; ++iter)
        std:cout << iter->first << " is " << iter->second << std::endl;
}
 

发布了64 篇原创文章 · 获赞 3 · 访问量 4573

猜你喜欢

转载自blog.csdn.net/qq_37631516/article/details/103787234