You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
vector<int> vec = {1,2,3,4,5};
auto first = vec.begin();
auto second = vec.begin() + 1;
auto third = vec.begin() + 2;
auto ret = vec.erase(second);
//first指向1,second和third失效//ret指向3(当前在second的位置)
纯属试水)
命名空间
定义了一堆内容(常量、变量、结构、类、函数……)的地方。
定义一个命名空间,方法和定义一个类差不多,只不过不需要末尾分号。
使用时:空间名::变量名。
using声明:
STL初步
标准模板库。含有算法、容器、函数、迭代器四个组件。
模板编写,分离数据和操作。
命名空间是std。可以用std::名字 来使用stl的函数或对象。
STL容器:简单容器
(1) Pair
(2)tuple
若干成员组成的元组,高级版pair。
获取数据:get函数。v0 = std::get<0>(tuple1); 上面尖括号里面是下标,不可以是变量。
下标需要在编译时确定:不能设定运行时可变的长度,不能当做数组。
创建:make_tuple. 参数表里是n个数据。这个n决定了tuple的长度。auto t = std::make_tuple(“abc”, 7.8, 123, ‘3’);
创建/修改数据:tie函数可以返回左值引用的元组。
std::string x; double y; int z;
std::tie(x, y, z) = std::make_tuple(“abc”, 7.8, 123);
//等价于 x = "abc"; y = 7.8; z = 123
std::tie(x, y, z) 就是tuple的左值引用。(x,y,z就是数据成员的左值引用)
这样可以给x,y,z赋值。改变他们时,tuple也就变了。
在这样操作之后,xval和halfx的值就被更新了。
这里maketuple是作为了传递返回值的工具。
额外示例:
(1)vector
自动扩展容量的数组。循序。
可以替代原生数组。
可以直接用下标访问。
创建:和创建类模板的实例没有区别。在尖括号里指明数据的类型。std::vector x
取长度:x.size();
清空:x.clear();
末尾加入元素:x.push_back(component);
删除末尾元素:x.pop_back();
在中间添加或删除:x.insert(x.begin()+1, 数据); x.erase(x.begin()+1);
遍历vector:
**上面两种写法走的都是迭代器;但如果这么写走的就是元素了:(for auto i: vec)
这样i就是元素的类型而不是迭代器。
erase函数:删除迭代器指向的元素而不是迭代器本身。例如:
auto it = vec.begin();
vec.erase(it);//删除它指向的元素,不是删除迭代器
迭代器的失效:
调用push_back等修改vector大小的方法时,可能会使所有迭代器失效(为什么?)(因为Push_back到了一定程度之后,可能会造成数组的整体移动,导致所有的内存地址发生改变。)
因此在遍历过程中添加元素可能导致迭代器失效。其实就是,当size==capacity时,继续push_back会导致迭代器失效。
上面的解释: erase的返回值也是迭代器。当删除second时,删除的不是那个叫做second的迭代器,而是它指向的元素2. 这时2后面的元素3顶上来,替代了2的位置。因此ret作为erase(second)的返回值,其实指向的就是原先second指向的位置,这个位置上现在是顶上来的3.
在修改过容器后,不使用之前的迭代器。
(2)list 链表
定义:std::list l; 跟前面都一样,尖括号用来实例化。
操作:
插入前端: push_front(数据);
插入末端:push_back(数据);
查询:find函数,返回迭代器。std::find(l.begin(), l.end(), 2);Find的第三个参数是什么意思?应该是从开头到结尾找值为2的元素。会返回查询结果的迭代器。
find的使用额外示例:
find感觉不是很好用,主要困难点在于返回的是迭代器。那我们在实际使用它的时候,一般会和那些接受迭代器做参数的函数一起。
插入指定位置:insert( it(位置), 数据);
不支持下标等随机访问,访问主要依靠迭代器。
插入和删除操作不会导致迭代器失效**(除指向被删除的元素的迭代器外)**
STL容器:关联容器
(1)set 无序集合
定义:std::set s;
特点:不重复元素组成的集合。不保持插入顺序,内部按大小排序。
操作:
s.find(val); //返回迭代器,这是find的特征。
s.erase(s.find(val)); //导致迭代器失效
统计值为val的元素的数目:返回数字。
(2)map 关联数组
Map是个词典。存储键值对。
Key就像是查询项,如下标。称为键。
T则是内容。称为值。
元素类型为pair<Key, T>。
可以通过下标(也就是键key)(可以不是整数,可以是各种类型比如string)进行访问。如果元素不存在,则创建对应元素。
可以用insert插入。
其它操作:
s.find(key); // 返回迭代器
统计键为key的元素个数:
s.count(key); // 返回0或1
删除:
s.erase(s.find(key)); //导致被删元素的迭代器失效
STL容器:总结
序列容器与关联容器的区别:
The text was updated successfully, but these errors were encountered: