C++ set用法

C++ set用法


一、set介绍


vector封装数组,list封装了链表,map和set封装了二叉树

set 翻译为集合,是一个内部自动有序且不含重复元素的容器。

当出现需要去掉重复元素的情况,而且有可能因这些元素比较大或者类型不是 int 型而不能直接开散列表,在这种情况下就可以用 set 来保留元素本身而不考虑它的个数。

当然,上面说的情况也可以通过再开一个数组进行下标和元素的对应来解决,但是set提供了更为直观的接口,并且加入set之后可以实现自动排序。

二、set定义


set<typename> name;

//这里的typename可以是任何基本类型,例如 int、double、char、结构体等,也可以是STL标准容器,例如vector、set、queue等。

定义 set 数组:

set<typename> Arrayname[arraySize];

这样 Arrayname[0] ~ Arrayname[arraySize -1] 中每一个都是一个 set 容器。

三、set 容器内元素的访问


set 只能通过迭代器访问:set<typename>::iterator it;

eg:

#include<stdio.h>
#include<set>
using namespace std;
int main()
{
    set<int> st;
    for (int i = 1; i <= 5; i++)
    {
       st.insert(i);
    }
    for (set<int>::iterator it = st.begin(); it != st.end(); it++)
    {
       printf("%d ", *it);
    }
    return 0;
}

四、set 常用函数实例解析


(1)insert()

insert(x) 可将 x 插入 set 容器中,并自动递增排序和去重,时间复杂度为 O(logN),其中 N 为 set 内的元素个数。

(2)find()

find(value) 返回 set 中对应值为 value 的迭代器,时间复杂度为 O(logN),其中 N 为 set 内的元素个数。

Eg:

int main()

{

​    set<int> st;

​    for (int i = 5; i >= 1; i--)

​    {

​       st.insert(i);

​    }

​    set<int>::iterator it = st.find(2); //在 set 中查找2,返回其迭代器。

​    printf("%d ", *it);

​    return 0;

}

(3)erase()

1.删除单个元素。

删除单个元素有两种方法:

(1)st.erase(it) ,即删除迭代器为 it 处的元素,时间复杂度为 O(1)。可以结合 find() 函数来使用。示例如下:

int main()

{

​    set<int> st;

​    for (int i = 5; i >= 1; i--)

​    {

​       st.insert(i*100);

​    }

​    st.erase(st.find(200)); //利用 find() 函数找到200,然后用 erase 删除它。

​    for (set<int>::iterator it = st.begin(); it != st.end(); it++)

​    {

​       printf("%d \n", *it);

​    }

​    return 0;

}

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

int main()
{
    set<int> st;
    for (int i = 5; i >= 1; i--)
    {
       st.insert(i*100);
    }
    st.erase(200); //用 erase 删除200。
    for (set<int>::iterator it = st.begin(); it != st.end(); it++)
    {
       printf("%d \n", *it);
    }
    return 0;
}

2.删除一个区间内的所有元素。

erase(first,last) 即删除 [first,last) 内的所有元素。其中 first 为所需要删除区间的起始迭代器,而 last 则为所需要删除区间的末尾迭代器的下一个地址。时间复杂度为 O(last-first)。

int main()
{
    set<int> st;
    for (int i = 5; i >= 1; i--)
    {
       st.insert(i*100);
    }
    st.erase(st.find(300),st.end());
    for (set<int>::iterator it = st.begin(); it != st.end(); it++)
    {
       printf("%d \n", *it);
    }
    return 0;
}

(4)size()

size() 用来获得 set 中元素的个数,时间复杂度为 O(1)。size()返回的是 unsigned 类型,不过一般来说用 %d 不会出很大问题,这一点对所有 STL 容器都是一样的。

(5)clear()

clear() 用来清空 set 中的所有元素,时间复杂度为 O(N),其中 N 为 set 中元素的个数。

(6)count()

用来查找set中某个某个键值出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了。

五、set 的常见用途


set 最主要的作用是自动去重并按升序排序,因此碰到需要去重但是却不方便直接开数组的情况,可以用 set 解决

set 中元素是唯一的,如果需要处理不唯一的情况,则需要使用 multiset

unordered_set 可以用来处理只去重但不排序的需求,速度比 set 要快得多。

Eg:

int main(){
    set<int>st;
    for(int i=1;i<=5;i++){
       st.insert(i*100);
    }
    cout<<"数组的size:"<<st.size()<<endl;
    cout<<"数组的最大size:"<<st.max_size()<<endl;
    cout<<"数组的第一个元素:"<<*st.begin() <<endl;
    cout<<"数组的第后个元素:"<<*(--st.end() )<<endl;
    cout<<"set 中 100 出现的次数是 :"<<st.count(100)<<endl;
    st.clear();
    if(st.size()==0)cout<<"st空了"<<endl;
}
### C++ 中 `set` 的数据结构及其使用方法 #### 什么是 `set` `set` 是 C++ STL 提供的一种关联容器,它存储的是唯一的键值集合,并按照升序排列。其底层实现通常基于红黑树(一种自平衡二叉搜索树),因此能够提供高效的插入、删除和查找操作。 #### 基本特性 - **唯一性**:`set` 容器中的元素不允许重复。 - **有序性**:默认情况下,`set` 中的元素会按从小到大顺序自动排序。 - **时间复杂度**: - 插入/删除/查找的时间复杂度均为 O(log n),这是因为它的内部实现了红黑树[^4]。 --- #### 如何定义 `set` 可以通过指定模板参数来创建不同类型的 `set`: ```cpp #include <set> std::set<int> mySet; // 存储整数,默认按升序排列 std::set<std::string> strSet; // 存储字符串,默认字典序排列 ``` 如果需要改变默认的排序方式,可以在第二个模板参数中传入一个比较函数或仿函数: ```cpp struct cmp { bool operator()(int a, int b) const { return a > b; } }; std::set<int, cmp> descendingSet; // 按降序排列 ``` 上述代码通过自定义仿函数 `cmp` 实现了一个降序排列的 `set`[^1]。 --- #### 常见操作 ##### 插入元素 使用 `insert()` 方法向 `set` 中添加新元素: ```cpp mySet.insert(10); mySet.insert(20); mySet.insert(10); // 不会产生任何效果,因为 10 已经存在 ``` ##### 遍历元素 可以使用范围 `for` 或迭代器遍历来访问 `set` 中的所有元素: ```cpp // 范围 for 循环 for (int elem : mySet) { std::cout << elem << " "; } // 迭代器遍历 for (auto it = mySet.begin(); it != mySet.end(); ++it) { std::cout << *it << " "; } ``` 以上两种方式都可以用来打印 `set` 中的所有元素[^2]。 ##### 查找元素 利用 `find()` 函数定位某个特定值的位置。如果没有找到,则返回 `end()`: ```cpp if (mySet.find(10) != mySet.end()) { std::cout << "Element found!" << std::endl; } else { std::cout << "Element not found." << std::endl; } ``` ##### 删除元素 可通过 `erase()` 方法移除单个元素或多组连续元素: ```cpp mySet.erase(10); // 移除值为 10 的元素 mySet.erase(mySet.begin()); // 移除首个元素 ``` --- #### 示例程序 下面展示如何综合运用 `set` 的基本功能: ```cpp #include <iostream> #include <set> int main() { std::set<int> mySet; // 插入元素 mySet.insert(50); mySet.insert(30); mySet.insert(20); // 打印所有元素 std::cout << "Elements in the set:" << std::endl; for (const auto& elem : mySet) { std::cout << elem << " "; } // 查找元素 int key = 30; if (mySet.find(key) != mySet.end()) { std::cout << "\nKey " << key << " exists in the set.\n"; } else { std::cout << "\nKey does not exist in the set.\n"; } // 删除元素 mySet.erase(30); // 再次打印剩余元素 std::cout << "After deletion:\n"; for (const auto& elem : mySet) { std::cout << elem << " "; } return 0; } ``` 运行结果可能如下所示: ``` Elements in the set: 20 30 50 Key 30 exists in the set. After deletion: 20 50 ``` --- #### 多重集 (`multiset`) 与普通的 `set` 类似,但允许其中包含重复的元素。其余特性和用法几乎一致。 ```cpp #include <set> #include <iostream> void testMultiset() { std::multiset<int> ms; ms.insert(5); ms.insert(5); ms.insert(2); for (auto it = ms.begin(); it != ms.end(); ++it) { std::cout << *it << " "; } } ``` 此代码片段展示了多重集中可容纳多个相同数值的情况。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值