一文看懂STL标准模板中的set用法(C++)详细源码与例题

在 C++ 中,集合通常指的是标准模板库(STL)中的 std::set 或 std::unordered_set。这两个都是用来存储不重复元素的容器,但在实现和使用方式上有一些区别。

集合(set)是一个内部自动有序且不含重复元素的容器,它可以在需要删除重复元素的情况下大放异彩,节省时间,减少思维量。

set 就是关键字的简单集合,当只是想知道一个值是否存在时,set 是最有用的。

顺序容器包括 vector、list、forward_list、array、string,所有顺序容器都提供了快速顺序访问元素的能力;关联容器包括 set、map

标准库提供 set 关联容器分为:

按关键字有序保存元素:set(关键字即值,即只保存关键字的容器)、multiset(关键字可重复出现的 set);

无序集合:unordered_set(用哈希函数组织的 set)、unordered_multiset(用哈希函数组织的 set,关键字可以重复出现)。

图片

图片

代码演示如下:

#include <iostream>#include <set>using namespace std;int main(){  set<int> s;  s.insert(5);  s.insert(2);  s.insert(6);  for (set<int>::iterator it = s.begin(); it != s.end(); it++){    cout << *it << " ";  }  return 0;}

使用时需包含头文件:​​​​​​​

#include <set>using namespace std;


std::set:

•元素按照严格的顺序(默认是升序)排列。

•插入、查找、删除操作的平均时间复杂度为 O(log n)。

•不支持直接修改元素的值,但可以通过删除再插入的方式来实现。

std::unordered_set:

•基于哈希表实现,元素无序存储。

•插入、查找、删除操作的平均时间复杂度为 O(1)。

•元素类型必须支持哈希函数,或者提供自定义的哈希函数。

3.要判断一个元素是否在集合中

使用集合的 find() 函数。这个函数会返回一个迭代器,如果找到了元素,则返回指向该元素的迭代器;如果未找到,则返回集合的 end() 迭代器。

4.erase():可 以删除单个元素或删除一个区间内的所有元素

删除单个元素:

1.st.erase(it),其中 it 为所需要删除元素的迭代器。时间复杂度为 O(1),可以结合 find() 函数来使用。

2.st.erase(value),其中 value 为所需要删除元素的值。时间复杂度为 O(logN),N 为 set 内的元素个数。

#include <iostream>#include <set>using namespace std;int main(){  set<int> st;  st.insert(100);  st.insert(200);  st.insert(100);  st.insert(300);  st.insert(500);  // 删除单个元素  st.erase(st.find(100)); // 利用find()函数找到100,然后用erase删除它  st.erase(200); // 删除值为200的元素  for (set<int>::iterator it = st.begin(); it != st.end(); it++)  {    cout << *it << " ";  }  return 0;}// 输出结果300 500

删除一个区间内的所有元素:

st.erase(iteratorBegin, iteratorEnd),其中 iteratorBegin 为所需要删除区间的起始迭代器, iteratorEnd 为所需要删除区间的结束迭代器的下一个地址,即取 [iteratorBegin, iteratorEnd​​​​​​​

#include <iostream>#include <set>using namespace std;int main(){  set<int> st;  st.insert(100);  st.insert(200);  st.insert(100);  st.insert(300);  st.insert(500);  set<int>::iterator it = st.find(300);  // 删除一个区间内的所有元素  st.erase(it, st.end());  for (it = st.begin(); it != st.end(); it++)  {    cout << *it << " ";  }  return 0;}

题目描述

给定 n 个数,要求把其中重复的去掉,只保留第一次出现的数。

输入格式

本题有多组数据。

第一行一个整数 TT,表示数据组数。

对于每组数据:

第一行一个整数 nn。

第二行 nn 个数,表示给定的数。

输出格式

对于每组数据,输出一行,为去重后剩下的数,两个数之间用一个空格隔开。

输入输出样例

输入 #1复制

2
11
1 2 18 3 3 19 2 3 6 5 4
6
1 2 3 4 5 6

输出 #1复制

1 2 18 3 19 6 5 4
1 2 3 4 5 6

#include <iostream>#include <set>#include <vector>using namespace std;
int T;
int main(){    cin >> T;    while(T--){        int n;        cin >> n;
        vector<int> num(n);        for(int i=0; i < n;i++){            cin >> num[i];        }
        set<int> seen; // 记录已经出现的数字        vector<int> res;
        for(int i=0;i < n;i++){            if(seen.find(num[i]) == seen.end() ){                res.push_back(num[i]);                seen.insert(num[i]); // 标记为已经出现过            }        }        for(int i=0;i < res.size();i++){            if(i > 0) cout << " ";            cout << res[i];        }        cout << endl;    }}
  • 20
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饿了就去喝水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值