序列容器
创建矢量容器
#include <vector>
int main()
{
std::vector<int> mydata{10};
mydata.push_back(9);
std::cout << "data size :"<<mydata.size() << std::endl;
std::cout << "vector data :" << *mydata.data() << std::endl;
mydata.push_back(8);
mydata.push_back(7);
mydata.push_back(6);
mydata.push_back(5);
std::cout << "using begin and end :" << std::endl;
std::vector<int>::iterator mydata_iterator = mydata.begin();
std::cout << "dtat begin +1 :" << *(mydata_iterator+1) << std::endl;
for (; mydata_iterator!= mydata.end(); mydata_iterator++)
{
std::cout << *mydata_iterator << std::endl;
}
}
矢量容器的容量和大小
#include <vector>
int main()
{
std::vector<int> mydata{10};
mydata.push_back(9);
std::cout << "data size :"<<mydata.size() << std::endl;
std::cout << "vector data :" << *mydata.data() << std::endl;
mydata.push_back(8);
mydata.push_back(7);
mydata.push_back(6);
mydata.push_back(5);
std::cout << "using begin and end :" << std::endl;
std::vector<int>::iterator mydata_iterator = mydata.begin();
std::cout << "dtat begin +1 :" << *(mydata_iterator+1) << std::endl;
for (; mydata_iterator!= mydata.end(); mydata_iterator++)
{
std::cout << *mydata_iterator << std::endl;
}
std::cout << "vector capacity :" << mydata.capacity() << std::endl;
}
访问矢量中的元素
#include <vector>
int main()
{
std::vector<int> mydata{10};
mydata.push_back(9);
std::cout << "data size :"<<mydata.size() << std::endl;
std::cout << "vector data :" << *mydata.data() << std::endl;
std::cout << "vector at(0) :" << mydata.at(0) << std::endl;
std::cout << "vector[1] :" << mydata[1] << std::endl;
}
在矢量中插入和删除元素
#include <vector>
int main()
{
std::vector<int> mydata{10};
mydata.push_back(9);
mydata.push_back(8);
mydata.push_back(7);
std::vector<int>::iterator mydata_iterator = mydata.begin();
for (; mydata_iterator != mydata.end(); mydata_iterator++)
{
std::cout << *mydata_iterator << std::endl;
}
std::cout << "after pop_back" << std::endl;
mydata.pop_back();
mydata_iterator = mydata.begin();
for (; mydata_iterator != mydata.end(); mydata_iterator++)
{
std::cout << *mydata_iterator << std::endl;
}
mydata_iterator = mydata.insert(mydata.begin()+1,99);
std::cout << "after insert with return iterator :" << std::endl;
for (; mydata_iterator != mydata.end(); mydata_iterator++)
{
std::cout << *mydata_iterator << std::endl;
}
mydata_iterator=mydata.emplace(mydata.begin() + 1, 999);
std::cout << "after emplace with return iterator :" << std::endl;
for (; mydata_iterator != mydata.end(); mydata_iterator++)
{
std::cout << *mydata_iterator << std::endl;
}
mydata_iterator = mydata.erase(mydata.begin() + 1);
std::cout << "after erase with return iterator :" << std::endl;
for (; mydata_iterator != mydata.end(); mydata_iterator++)
{
std::cout << *mydata_iterator << std::endl;
}
}
在矢量中存储类对象
矢量元素的排序
存储矢量中的指针
双端队列容器
对线性排列中给定类型的元素进行排序,并且类似于矢量,允许快速随机访问任何元素并在容器后面高效插入和删除。 但是,和矢量不同的是,deque
类还支持在容器前面高效插入和删除。
#include "pch.h"
#include <iostream>
#include <deque>
#include <algorithm> // For sort<T>()
#include <numeric> // For accumulate<T>()
#include <functional> // For transparent operator functors
int main()
{
std::deque<int> mydata{0};
mydata.push_front(1);
mydata.push_front(2);
mydata.push_back(3);
mydata.push_back(4);
for (const auto& n:mydata)
{
std::cout << n << " ";
}
std::cout << std::endl;
std::cout << std::endl;
for (auto _iter=crbegin(mydata);_iter!=crend(mydata); ++_iter)
{
std::cout << *_iter << " ";
}
std::cout << std::endl;
std::cout << std::endl;
for (auto _iter = mydata.begin(); _iter != mydata.end(); ++_iter)
{
std::cout << *_iter << " ";
}
std::cout << std::endl;
std::cout << std::endl;
std::sort(mydata.begin(), mydata.end(),std::greater<>());
for (const auto& n : mydata)
{
std::cout << n << " ";
}
std::cout << std::endl;
std::cout << std::endl;
std::cout << std::endl << "The sum of the elements in the queue is: "
<< std::accumulate(mydata.begin(), mydata.end(), 0) << std::endl;
std::cout << std::endl;
std::cout << std::endl << "The size of the elements in the queue is: "
<< mydata.size() << std::endl;
}
使用列表容器
C++ 标准库列表类是序列容器的类模板,用于在线性排列中维护其元素,并允许在序列中的任何位置高效插入和删除。 序列存储为元素的双向链接列表,每个列表包含某种类型的 Type
成员。
#include "pch.h"
#include <iostream>
#include <list>
#include <string>
#include <functional>
using std::string;
void listAll(const std::list<string>& strings)
{
for (auto& s : strings)
std::cout << s << std::endl;
}
int main()
{
std::list<string> text;
// Read the data
std::cout << "Enter a few lines of text. Just press Enter to end:" << std::endl;
string sentence;
while (getline(std::cin, sentence, '\n'), !sentence.empty())
text.push_front(sentence);
std::cout << "Your text in reverse order:" << std::endl;
listAll(text);
text.sort(); // Sort the data in ascending sequence
std::cout << "\nYour text in ascending sequence:" << std::endl;
listAll(text);
text.sort(std::greater<>()); // Sort the data in descending sequence
std::cout << "\nYour text in descending sequence:" << std::endl;
listAll(text);
}
使用forward_list容器
描述用于控制变长元素序列的对象。 序列存储为节点的单向链接列表,其中每个节点都包含 Type
类型的成员。
template <class Type,
class Allocator = allocator<Type>>
class forward_list
Type
要存储在 forward_list 中的元素数据类型。
Allocator
存储的分配器对象,该对象封装有关内存forward_list分配和解除分配的详细信息。 此参数是可选的。 默认值为分配器<Type>。
对象forward_list
通过基于分配器类 (通常称为std::allocator)
分配器类的存储对象,为其控件的序列分配和释放存储。 有关详细信息,请参阅分配器。 分配器对象必须具有与类型 allocator
对象相同的外部接口。
通过 forward_list
擦除迭代器、指针和引用所控制序列的元素时,这些迭代器、指针和引用可能失效。 通过 forward_list
对受控序列执行插入和接合操作不会使迭代器失效。
调用 forward_list::insert_after(它是可调用构造函数 Type(const T&)
的唯一成员函数)时,可能会添加受控序列。 forward_list
也可能调用移动构造函数。 如果此类表达式引发异常,则容器对象不插入任何新元素,并重新引发该异常。 因此,当发生此类异常时,类型的 forward_list
对象将处于已知状态。
使用其他序列容器
一个模板容器适配器类,它提供功能的限制,限制对一些基本容器类型的前端和后端元素的访问权限。 元素可以在后面添加或从前面移除,并且可以在任一端 queue
检查元素。
template <class Type, class Container = deque <Type>>
class queue
Type
要在 queue 中存储的元素数据类型。
Container
用于实现基础 queue容器的类型。
对象第一个queue
模板参数中规定类Type
的元素是同义value_type词,并且必须与第二个模板参数规定的基础容器类Container
中的元素的类型匹配。 Type
必须可分配,以便可以复制该类型的对象,并将值分配给该类型的变量。
适合的基础容器类,包括queue
deque和list,或支持、back
和push_back
pop_front
操作front
的任何其他序列容器。 基础容器类封装在容器适配器中,容器适配器仅公开一组有限的序列容器成员函数为公共接口。
queue
如果类的元素相等且仅当类Type
的元素可相等且仅当类的元素小于可比较时,对象相等,并且仅当类Type
的元素小于可比较时,对象才相等。
C++ 标准库定义了三种类型的容器适配器:stack
queue
和priority_queue
。 每种适配器都限制了一些基础容器类的功能,以便对标准数据结构提供精确控制的接口。
-
该stack类支持最后一个先出 (LIFO) 数据结构。 记住的一个很好的模拟将是一堆盘子。 元素(盘子)只能从堆栈顶部(基容器末尾的最后一个元素)插入、检查或删除。 仅访问顶部元素的限制是使用该
stack
类的原因。 -
该
queue
类支持先入先出 (FIFO) 数据结构。 记住的一个很好的模拟是人们排队为银行讲员。 元素(人)可从行的后部添加,并且可以从行的前部删除。 行的前部和后部都可以插入。 仅以这种方式访问front
和back
元素的限制是使用queue
类的原因。 -
类priority_queue按其元素排序,以便最大元素始终位于顶部位置。 它支持元素的插入以及顶部元素的检查和删除。 一个很好的模拟是人们排队安排他们的年龄,高度或其他一些标准。
priority_queue 类 | Microsoft Docs详细了解:priority_queue类https://docs.microsoft.com/zh-cn/cpp/standard-library/priority-queue-class?view=msvc-170一个模板容器适配器类,它提供功能的限制,限制一些基本容器类型顶端元素的访问权限,并且该类通常为最大类或具有最高优先级。 可以向新 priority_queue
元素添加,并且可以检查或删除该元素的 priority_queue
顶部元素。
template <class Type, class Container= vector <Type>, class Compare= less <typename Container ::value_type>>
class priority_queue
Type
要在 priority_queue 中存储的元素数据类型。
Container
用于实现基础 priority_queue容器的类型。
Compare
提供一个函数对象的类型,该对象可将两个元素值进行比较作为排序键来确定其相对顺序 priority_queue。 此参数为可选自变量,默认值是二元谓词 less<typename Container::value_type>。
备注
队列对象第一个模板参数中规定的类 Type
元素是同义 value_type 词,并且必须与第二个模板参数规定的基础容器类 Container
中的元素的类型匹配。 Type
必须可分配,以便复制该类型的对象并将值分配给该类型的变量。
通过 priority_queue
调用类 Traits
的存储函数对象对它控制的顺序进行排序。 通常,元素只需小于可比建立此顺序:因此,鉴于任何两个元素,可以确定它们等效 (,即既不小于其他) ,也不小于另一个元素。 这将导致在非等效元素之间进行排序。 在技术性更强的说明中,比较函数是一个二元谓词,在标准数学的意义上引发严格弱排序。
适合的基础容器类,包括priority_queue
deque类和默认vector类或任何其他支持操作的front
push_back
序列容器,以及pop_back
随机访问迭代器。 基础容器类封装在容器适配器中,容器适配器仅公开一组有限的序列容器成员函数为公共接口。
将元素添加到和移出 priority_queue
均存在对数复杂性。 访问 priority_queue
中的元素存在恒定的复杂性。
C++ 标准库定义了三种类型的容器适配器:stack
queue
和priority_queue
。 每种适配器都限制了一些基础容器类的功能,以便对标准数据结构提供精确控制的接口。
-
该stack类支持最后一个先出 (LIFO) 数据结构。 可以在脑海中将其类比为一摞盘子。 元素(盘子)只能从堆栈顶部(基容器末尾的最后一个元素)插入、检查或删除。 仅访问顶部元素的限制是使用该
stack
类的原因。 -
该queue类支持先入先出 (FIFO) 数据结构。 可以在脑海中将其类比为排队等候银行柜员的人。 元素(人)可从行的后部添加,并且可以从行的前部删除。 行的前部和后部都可以插入。 以这种方式仅访问前和后部元素的限制是使用
queue
类的原因。 -
类
priority_queue
按其元素排序,以便最大元素始终位于顶部位置。 它支持元素的插入以及顶部元素的检查和删除。 记住的一个很好的相似之处是人们排队安排他们的年龄、身高或其他一些标准。
一种模板容器适配器类,它提供了功能的限制,限制对最近添加到某些基础容器类型的元素的访问。 stack
当必须明确仅stack
对容器执行操作时,将使用该类。
template <class Type, class Container= deque <Type>>
class stack
Type
要存储在堆栈中的元素数据类型。
Container
用来实现堆栈的基础容器的类型。 默认值为类 deque<Type>。
备注
堆栈对象的第一个模板参数中规定的类 Type
元素是同 value_type 义词,并且必须与第二个模板参数规定的基础容器类 Container
中的元素类型匹配。 Type
必须可分配,以便可以复制该类型的对象,并将值分配给该类型的变量。
适用于堆栈的基础容器类包括deque、list类和vector类,或者支持操作back
push_back
pop_back
和操作的任何其他序列容器。 基础容器类封装在容器适配器中,容器适配器仅公开一组有限的序列容器成员函数为公共接口。
stack
当类的元素相等且仅当类Type
的元素相等且仅当类的元素小于可比时,对象是相等的,并且仅当类Type
的元素小于可比时,对象是相等的。
-
该
stack
类支持最后一个先出 (LIFO) 数据结构。 可以在脑海中将其类比为一摞盘子。 元素(盘子)只能从堆栈顶部(基容器末尾的最后一个元素)插入、检查或删除。 仅访问顶部元素的限制是使用该stack
类的原因。 -
该queue类支持先入先出 (FIFO) 数据结构。 可以在脑海中将其类比为排队等候银行柜员的人。 元素(人)可从行的后部添加,并且可以从行的前部删除。 行的前部和后部都可以插入。 以这种方式仅访问前端和后部元素的限制是使用
queue
类的毛皮的原因。 -
类priority_queue将按其元素排序,以便最大元素始终位于顶部位置。 它支持元素的插入以及顶部元素的检查和删除。 可以在脑海中将其类比为按年龄、身高或其他标准排队的人。
tuple[ ]类模板
包装元素的固定长度序列。
class tuple {
tuple();
explicit tuple(P1, P2, ..., PN); // 0 < N
tuple(const tuple&);
template <class U1, class U2, ..., class UN>
tuple(const tuple<U1, U2, ..., UN>&);
template <class U1, class U2>
tuple(const pair<U1, U2>&); // N == 2
void swap(tuple& right);
tuple& operator=(const tuple&);
template <class U1, class U2, ..., class UN>
tuple& operator=(const tuple<U1, U2, ..., UN>&);
template <class U1, class U2>
tuple& operator=(const pair<U1, U2>&); // N == 2
};
TN
第 N 个元组元素的类型。
备注
类模板描述一个对象,该对象分别存储类型 T1
N 个对象、T2
...、TN
...0 <= N <= Nmax
元组实例 tuple<T1, T2, ..., TN>
的范围是其模板参数的数目 N
。 模板参数 Ti
的索引以及该类型的相应存储值是 i - 1
。 因此,虽然我们在本文档中将类型编号为 1 到 N,但相应的索引值范围为 0 到 N - 1。
// tuple.cpp
// compile with: /EHsc
#include <vector>
#include <iomanip>
#include <iostream>
#include <tuple>
#include <string>
using namespace std;
typedef tuple <int, double, string> ids;
void print_ids(const ids& i)
{
cout << "( "
<< get<0>(i) << ", "
<< get<1>(i) << ", "
<< get<2>(i) << " )." << endl;
}
int main( )
{
// Using the constructor to declare and initialize a tuple
ids p1(10, 1.1e-2, "one");
// Compare using the helper function to declare and initialize a tuple
ids p2;
p2 = make_tuple(10, 2.22e-1, "two");
// Making a copy of a tuple
ids p3(p1);
cout.precision(3);
cout << "The tuple p1 is: ( ";
print_ids(p1);
cout << "The tuple p2 is: ( ";
print_ids(p2);
cout << "The tuple p3 is: ( ";
print_ids(p3);
vector<ids> v;
v.push_back(p1);
v.push_back(p2);
v.push_back(make_tuple(3, 3.3e-2, "three"));
cout << "The tuples in the vector are" << endl;
for(vector<ids>::const_iterator i = v.begin(); i != v.end(); ++i)
{
print_ids(*i);
}
}
Output:
The tuple p1 is: ( 10, 0.011, one ).
The tuple p2 is: ( 10, 0.222, two ).
The tuple p3 is: ( 10, 0.011, one ).
The tuples in the vector are
( 10, 0.011, one ).
( 10, 0.222, two ).
( 3, 0.033, three ).
关联容器
用于存储和检索集合中的数据,此集合中的每个元素均为包含数据值和排序键的元素对。 键的值是唯一的,用于自动排序数据。
可以直接更改映射中的元素值。 键值是常量,无法更改。 必须先删除与旧元素关联的键值,才能为新元素插入新键值。
template <class Key,
class Type,
class Traits = less<Key>,
class Allocator=allocator<pair <const Key, Type>>>
class map;
Key
要存储在中的 map键数据类型。
Type
要在 map 中存储的元素数据类型。
Traits
提供一个函数对象的类型,该对象可将两个元素值进行比较作为排序键来确定其相对顺序 map。 此参数为可选自变量,默认值是二元谓词 less<Key>。
在 C++14 中,可以通过指定 std::less<> 没有类型参数的谓词来启用异类查找。 有关详细信息 ,请参阅关联容器中的异类查找 。
Allocator
一种表示存储的分配器对象的类型,该分配器对象封装有关映射的内存分配和解除分配的详细信息。 此参数为可选参数,默认值为 allocator<pair<const Key, Type> >。
注解
C++ 标准库 map 类为:
-
大小可变的关联容器,基于关联键值高效检索元素值。
-
可逆,因为它提供双向迭代器来访问其元素。
-
有序,因为它的元素根据指定的比较函数按键值排序。
-
唯一。 因为它的每个元素必须具有唯一键。
-
关联容器对,因为它的元素数据值与其键值不同。
-
类模板,因为它提供的功能是泛型的,独立于元素或键类型。 用于元素和键的数据类型作为类模板以及比较函数和分配器中的参数指定。
映射类提供的迭代器是双向迭代器,但insertmap类成员函数具有作为模板参数的较弱输入迭代器的版本,其功能要求小于双向迭代器类保证的功能要求。 不同的迭代器概念通过它们的功能优化相关联。 每个迭代器概念有它自己的一套要求,使用这些概念的算法必须受这些要求的限制。 输入迭代器可取消引用以引用某个对象,并可递增到序列中的下一迭代器。
建议你根据应用程序需要的搜索和插入类型选择容器类型。 关联容器针对查找、插入和移除操作进行了优化。 显式支持这些操作的成员函数在最坏的情况下执行这些操作,这与容器中元素数的对数成正比。 插入元素不会使迭代器失效,移除元素仅会使专门指向已移除元素的迭代器失效。
建议你在应用程序满足将值与键关联的条件时,选择映射作为关联容器。 此类结构的模型是关键字排序列表,这些关键字只出现一次,并具有提供定义的关联字符串值。 如果单词具有多个正确的定义,以便键不唯一,则多重映射将是所选容器。 如果仅存储关键字列表,则应使用集作为适当容器。 如果允许关键字多次出现,则多重集合为适当容器。
映射通过调用类型 key_compare存储的函数对象对它控件的元素进行排序。 此存储对象是一个通过调用该方法访问的 key_comp 比较函数。 一般情况下,将比较任何两个给定元素,以确定一个元素是否小于另一个元素,或者它们是否等效。 比较所有元素后,将创建非等效元素的排序序列。
备注
比较函数是一个二元谓词,在标准数学的意义上引发严格弱排序。 二进制谓词 f (x,y) 是一个函数对象,其中包含两个参数对象 x 和 y,以及返回值 true
或 false
。 对集施加的排序是一个严格的弱排序,如果二进制谓词不灵活、反对称和可传递,如果等效性是可传递的,则当 f (x、y) 和 f (y,x) 时,两个对象 x 和 y 都 false
定义为等效。 如果键之间的更强相等条件取代了等效性,则排序将为总排序(即所有元素彼此排序),并且匹配的键将难以彼此辨别。
在 C++14 中,可以通过指定 std::less<>
没有类型参数的 std::greater<>
谓词来启用异类查找。 有关详细信息 ,请参阅关联容器中的异类查找 。
使用映射容器
使用多重映射容器