STL初讲

STL是C++的标准模板库
特点:好用、复杂,提供了多种组织数据的常用方法;
如:vector(向量,类似于数组)、list(列表,类似于链表)、deque(双向队列)、set(集合)、map(映像)、stack(栈)、queue(队列)等。
三大核心部分:容器(Container)、算法(Algorithms)、迭代器(Iterator),除此之外还有STL其他标准组件。
容器(container):容器是数据在内存中组织的方法,例如,数组、堆栈、队列、链表或二叉树(不过这些都不是STL标准容器)。STL中的容器是一种存储T(Template)类型值的有限集合的数据结构,容器的内部实现一般是类。这些值可以是对象本身,如果数据类型T代表的是Class的话。
算法(algorithm):算法是应用在容器上以各种方法处理其内容的行为或功能。例如,有对容器内容排序、复制、检索和合并的算法。在STL中,算法是由模板函数表现的。这些函数不是容器类的成员函数。相反,它们是独立的函数。令人吃惊的特点之一就是其算法如此通用。不仅可以将其用于STL容器,而且可以用于普通的C++数组或任何其他应用程序指定的容器。
迭代器(iterator):一旦选定一种容器类型和数据行为(算法),那么剩下唯一要他做的就是用迭代器使其相互作用。可以把达代器看作一个指向容器中元素的普通指针。可以如递增一个指针那样递增迭代器,使其依次指向容器中每一个后继的元素。迭代器是STL的一个关键部分,因为它将算法和容器连在一起。
模板类:
一,vector:向量,支持随机访问迭代器,所有STL算法都能对vector操作。随机访问时间为常数。在尾部添加速度很快,在中间插入慢。实际上就是动态数组,可直接赋值,也可作为函数的参数或者返回值,且函数传递时,无需指定元素个数。
1.创建:vector (int/double/string/…) name
eg:vector():无参数构建函数,并将容器置为空;
vector(int n):将容器初始化为N个元素;
vector(int n,const T &VAL):假定元素类型为T,将容器初始有n个元素,且值都为VAL;
vector(iterator first,iterator last):将容器初始化为同别的容器区间[first,last]相同的的内容;
vector(string)str 表示的是类似于string str[]的字符串数组
2.插入:insert,push_back
insert():可在vector对象的任意位置插入新的元素,并为vector自动扩张一个元素的空间,插入位置后的元素依次向后挪动一个位置(注:该方法插入的位置迭代器的位置,而不是元素下标的位置);
eg:vector(int)v;
v.insert(v.begin(),x) //在最前面插入元素X;
v.insert(v.bengin()+2,x)//在第二个位置插入元素X;
v.insert(v.end(),x)//在最后插入元素X;
push_back():在vector容器的尾部,追加新的元素;并自动分配新的内存空间;也可对空的vector进行扩展;
eg:v.push_back(X) //在最后面添加新的元素X;
3.删除:
erase() :可以删除vector中迭代器所指定的一个元素或一段区间中的所有元素;
eg:v.erase(v.begin()+2);//删除容器中的第二个元素,从零开始计数
v.erase(v.begin()+1,v.begin()+5);//删除区间[1,5]中的所有元素
clear():一次性删除vector中所有的元素;
4.遍历:常用迭代器配合循环语句对vector对象进行遍历;迭代器的类型一定要与遍历对象的类型一致;
eg:vector(int)::iterator it;
for(it=v.begin();it!=v.end();it++)
cout<<*it<<” “;//输出迭代器(类似指针)的值
5.查找:find()是使用迭代器,遍历vector容器,并查找相关元素,返回该元素的位置(即改变迭代器的值,同指针)
eg:vector ::iterator result=find(v.begin(),v.end(),X);//查找元素X的位置
if (result!=v.end()) //find it
cout << “find it!” << endl;
6.排序:使用 sort 算法要求使用随机访问迭代器进行排序,在默认的情况下,对向量元素进行升序排列;注意需要声明头文件 #include “algorithm”;还可以自己设计编写排序的比较函数,并指定给sort算法,sort便会根据指定的排序规则进行排序!
eg:字符串按1的个数排序

#include “cstdio>”  
#include <iostream>  
#include <string>  
#include <vector>  
#include <algorithm>  
using namespace std;  
bool MyComp(const string &s1,const string &s2)  
{  
    int c1=count(s1.begin(),s1.end(),'1');  
    int c2=count(s2.begin(),s2.end(),'1');  
    return c1!=c2?c1<c2:s1<s2;  
}
int main()  
{  
    vector<string>vstr;  
    string str;  
    while(cin>>str)  
    {  
        vstr.push_back(str);  
    }  
    sort(vstr.begin(),vstr.end(),MyComp);  
    for(vector<string>::iterator it=vstr.begin();it<vstr.end();it++)  
    {  
        cout<<*it<<endl;  
    }  
    return 0;  
}  

7.其他:
如 v.pop_back():删除最后一个元素;
v.size():读取容器大小;
v.resize():改变容器大小;
二.string:提供了string基本字符系列容器来处理字符串,可以把string理解为字符串类,它提供了添加、删除、替换、查找和比较等丰富的方法;
1.创建:string name;//创建了字符串对象name,name是一个空字符,长度为零,注:创建时,可对其赋初始值,也可在使用中,赋予其他值;

<think>我们被要求解C++中的set,并且最后提出3-5个相关问题,以"§§相关问题§§"开头。 注意:回答必须使用中文,最后部分必须包含相关问题,且第一行是"§§相关问题§§",禁止换行分散。 首先,我们需要解set的基本概念、特点、常用操作和示例代码。 内容安排: 1. set的定义:std::set是C++标准模板库(STL)中的关联容器,它存储唯一元素,并按照特定排序准则自动排序。 2. 特点:唯一键(元素唯一)、自动排序(默认升序)、基于红黑树实现(查找、插入、删除操作的时间复杂度为O(log n))。 3. 常用操作:插入、删除、查找、遍历等。 4. 代码示例:展示set的基本使用。 我们将编写一个简单的代码示例,展示set的常用操作。 注意:代码语言标记为cpp。 最后,根据解内容提出3-5个相关问题。 示例代码: ```cpp #include <iostream> #include <set> using namespace std; int main() { // 创建set set<int> mySet; // 插入元素 mySet.insert(3); mySet.insert(1); mySet.insert(4); mySet.insert(1); // 重复元素不会被插入 // 遍历set(自动排序) cout << "Set elements: "; for (int num : mySet) { cout << num << " "; } cout << endl; // 输出: 1 3 4 // 查找元素 int target = 3; auto it = mySet.find(target); if (it != mySet.end()) { cout << "Found " << target << endl; } else { cout << "Not found" << endl; } // 删除元素 mySet.erase(3); cout << "After erase 3: "; for (int num : mySet) { cout << num << " "; } cout << endl; // 输出: 1 4 return 0; } ``` 接下来,我们提出相关问题: 1. set和unordered_set在实现和性能上有何主要区别? 2. 如何在set中存储自定义类型?需要满足什么条件? 3. set的迭代器是双向迭代器还是随机访问迭代器?它支持哪些操作? 4. 如何获取set中某个元素出现的次数?为什么? 5. 在set中插入元素时,如何避免重复插入已存在的元素? 注意:问题数量在3到5个之间,我们选择5个。 最后,按照格式输出。 </think>### C++ 中 `std::set` 详解 `std::set` 是 C++ STL 中的**有序关联容器**,基于红黑树实现,具有以下核心特性: #### ✅ 核心特性 1. **自动排序** - 元素自动按严格弱序(默认为 `<` 运算符)排序 - 插入元素时会自动调整位置 ```cpp #include <set> std::set<int> numSet = {5, 2, 8, 1}; // 自动排序结果:{1, 2, 5, 8} ``` 2. **元素唯一性** - 拒绝重复元素(使用 `multiset` 允许重复) ```cpp numSet.insert(2); // 重复插入无效,size 不变 ``` 3. **高效查找** - 基于红黑树实现,查找时间复杂度 `O(log n)` ```cpp if (numSet.find(5) != numSet.end()) { // 找到元素 } ``` --- ### ️ 构造与始化方法 | 方法 | 示例代码 | |---------------------------|---------------------------------------------| | 默认构造 | `std::set<std::string> words;` | | 始化列表构造 | `std::set<int> primes = {2, 3, 5, 7};` | | 范围构造(迭代器) | `std::set<int> copySet(vec.begin(), vec.end());` | | 自定义比较器构造 | ```cpp struct CaseInsensitive { bool operator()(const std::string& a, const std::string& b) const { return std::lexicographical_compare( a.begin(), a.end(), b.begin(), b.end(), [](char c1, char c2){ return tolower(c1) < tolower(c2); }); } }; std::set<std::string, CaseInsensitive> insensitiveSet; ``` | --- ### 🔑 核心操作 1. **插入元素** ```cpp auto [iter, success] = numSet.insert(10); // C++17 结构化绑定 if (success) { /* 插入成功 */ } ``` 2. **删除元素** ```cpp numSet.erase(5); // 按值删除 numSet.erase(iter); // 按迭代器删除 ``` 3. **查找与访问** ```cpp auto it = numSet.find(8); // 返回迭代器 if (it != numSet.end()) { /* 存在 */ } ``` 4. **边界访问** ```cpp auto lower = numSet.lower_bound(4); // 首个≥4的元素 auto upper = numSet.upper_bound(7); // 首个>7的元素 ``` --- ### ️ 注意事项 1. **迭代器稳定性** - 除被删除元素外,迭代器不会失效 ```cpp auto it = numSet.begin(); numSet.insert(0); // it 仍然有效 ``` 2. **自定义类型要求** - 必须实现严格弱序比较(`operator<` 或自定义比较器) ```cpp struct Point { int x, y; bool operator<(const Point& p) const { return x == p.x ? y < p.y : x < p.x; } }; std::set<Point> points; ``` 3. **性能特点** | 操作 | 时间复杂度 | |------------|------------| | 插入/删除 | O(log n) | | 查找 | O(log n) | | 遍历 | O(n) | --- ### 与其他容器对比 | 特性 | `set` | `unordered_set` | `vector` | |---------------|----------------|-----------------|----------------| | **排序** | 有序 | 无序 | 有序(可排序) | | **查找速度** | O(log n) | O(1) 平均 | O(n) | | **重复元素** | 不允许 | 不允许 | 允许 | | **底层实现** | 红黑树 | 哈希表 | 动态数组 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值