首页 > 其他分享 >STL-Set集合

STL-Set集合

时间:2024-01-22 20:00:52浏览次数:20  
标签:std 容器 Set const 迭代 STL 元素 set 集合

STL-Set集合

目录

set 集合 unordered_set 无序集合

set的元素不像map那样可以同时拥有实值和键值,set的元素即是键值又是实值。 set不允许两个元素有相同的键值。

不允许出现相同的两个
set 根据元素的值,系统自动排序

底层原理 hash表

导入

#incude<set>
#incdue<unordered_set>

构造

常见的创建 set 容器的方法,大致有以下 5 种。

std::set<std::string> myset;   //默认构造函数

std::set<std::string> copyset(myset);  //复制构造
//等同于
//std::set<std::string> copyset = myset


set<string> mysets{"python","go","java"};  //构造初始化
std::set<std::string> myset{"python","go","java"};  //构造初始化


std::set<std::string> copyset(++myset.begin(), myset.end());   // 复制初始化


set<string, std::greater<string>> words {"one", "two", "three"};

插入删除

添加元素

//插入数据
set<string>  str_set;
str_set.insert("china");
str_set.insert("us");


set<string, greater<string>> words {"one", "two", "three"};

// 插入单个元素会返回一个 pair<iterator,bool> 对象。
auto pr1 = words.insert("four");
auto pr2 = words.insert ("two") ;

//插入单个元素和一个标识,会返回一个迭代器。
auto iter3 = words.insert(pr.first, "seven");

//插入一段元素或一个初始化列表就不会有返回值。
words.insert ({ "five","six"}) ;

//当 insert() 的参数是初始化列表时,会用列表中的字符串创建 string 对象
string wrds[] {"eight", "nine", "ten"};
words.insert(std::begin(wrds) , std::end(wrds));

删除元素

成员函数 clear() 会删除 set 的所有元素。成员函数 erase() 会删除迭代器指定位置的元素或与对象匹配的元素

//删除 set 容器中值为 val 的元素
size_type erase (const value_type& val);
//删除 position 迭代器指向的元素
iterator  erase (const_iterator position);
//删除 [first,last) 区间内的所有元素
iterator  erase (const_iterator first, const_iterator last);
#include <iostream>
#include <set>
#include <string>
using namespace std;
int main()
{
    //创建并初始化 set 容器
    std::set<int>myset{1,2,3,4,5};
    cout << "myset size = " << myset.size() << endl;
   
    //1. erase() 方法
    int num = myset.erase(2); //删除元素 2,myset={1,3,4,5}
    cout << "1. myset size = " << myset.size() << endl;
    cout << "num = " << num << endl;
    
    //2. erase() 方法
    set<int>::iterator iter = myset.erase(myset.begin()); //删除元素 1,myset={3,4,5}
    cout << "2. myset size = " << myset.size() << endl;
    cout << "iter->" << *iter << endl;
    
    //3. erase() 方法
    set<int>::iterator iter2 = myset.erase(myset.begin(), --myset.end());//删除元素 3,4,myset={5}
    cout << "3. myset size = " << myset.size() << endl;
    cout << "iter2->" << *iter2 << endl;
    return 0;
}

//myset size = 5
//1. myset size = 4
//num = 1
//2. myset size = 3
//iter->3
//3. myset size = 1
//iter2->5

删除 set 容器中存储的所有元素

#include <iostream>
#include <set>
#include <string>
using namespace std;
int main()
{
    //创建并初始化 set 容器
    std::set<int>myset{1,2,3,4,5};
    cout << "1. myset size = " << myset.size() << endl;
    //清空 myset 容器
    myset.clear();
    cout << "2. myset size = " << myset.size() << endl;
    return 0;
   

查找元素

find()函数用于查找具有给定值 val 的元素。如果找到元素,则返回指向该元素的迭代器

否则返回指向集合末尾的迭代器即set :: end()。

#include <iostream>
#include <set>

using namespace std;

int main(void) {
   set<int> m = {100,200,300,400};

   auto it = m.find(300);

   cout << "iter ->  " << *it << endl;

   return 0;
}
//iter ->  300
//打印输出
for(std::set<int>::iterator iter=chars.begin();iter!=chars.end();++iter){
    cout<< *iter<< endl;
    }


set<string> str_set;
str_set.insert("123")
set<string>::iterator  it= str_set.find("123"); 
cout<< *it<< endl;   //如果输出的是 123 则说明找到

//或者     
//返回一个迭代器  iterator  
if(str_set.find("123")!=str_end()){
    cout<<"find 123" <<endl;
}else {
    cout<<"not find 123"<<endl;
}
    
//是否在set中
//str_set.count();	

遍历元素

#include <iostream>
#include <set>
#include <string>
using namespace std;

int main()
{
    std::set<int> numbers{2, 4, 6, 8, 10, 12, 14};


    for (auto  it= numbers.begin(); it != numbers.end(); i++)
        cout << *it << " "; // 注意指针运算符

    numbers.clear();

    return 0;
}

成员方法

成员方法 功能
begin() 返回指向容器中第一个(注意,是已排好序的第一个)元素的双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
end() 返回指向容器最后一个元素(注意,是已排好序的最后一个)所在位置后一个位置的双向迭代器,通常和 begin() 结合使用。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
rbegin() 返回指向最后一个(注意,是已排好序的最后一个)元素的反向双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。
rend() 返回指向第一个(注意,是已排好序的第一个)元素所在位置前一个位置的反向双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。
cbegin() 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。
cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。
crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。
crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。
find(val) 在 set 容器中查找值为 val 的元素,如果成功找到,则返回指向该元素的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
lower_bound(val) 返回一个指向当前 set 容器中第一个大于或等于 val 的元素的双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
upper_bound(val) 返回一个指向当前 set 容器中第一个大于 val 的元素的迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
equal_range(val) 该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的值为 val 的元素(set 容器中各个元素是唯一的,因此该范围最多包含一个元素)。
empty() 若容器为空,则返回 true;否则 false。
size() 返回当前 set 容器中存有元素的个数。
max_size() 返回 set 容器所能容纳元素的最大个数,不同的操作系统,其返回值亦不相同。
insert() 向 set 容器中插入元素。
erase() 删除 set 容器中存储的元素。
swap() 交换 2 个 set 容器中存储的所有元素。这意味着,操作的 2 个 set 容器的类型必须相同。
clear() 清空 set 容器中所有的元素,即令 set 容器的 size() 为 0。
emplace() 在当前 set 容器中的指定位置直接构造新元素。其效果和 insert() 一样,但效率更高。
emplace_hint() 在本质上和 emplace() 在 set 容器中构造新元素的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示新元素生成位置的迭代器,并作为该方法的第一个参数。
count(val) 在当前 set 容器中,查找值为 val 的元素的个数,并返回。注意,由于 set 容器中各元素的值是唯一的,因此该函数的返回值最大为 1。

multiset

multiset特性及用法和set完全相同,唯一的差别在于它允许键值重复。set和multiset的底层实现是红黑树,红黑树为平衡二叉树的一种。

set<T> st;//set默认构造函数: 
mulitset<T> mst; //multiset默认构造函数: 
set(const set &st);//拷贝构造函数
#include <iostream>
#include <set>
using namespace std;

void printSetInt(multiset<int> &mset)
{
  
   for (auto  it = mset.begin(); it != mset.end(); it++)
   {
      cout << *it << " ";
   }
   cout << endl;
}
void test()
{
   multiset<int> s;
   s.insert(10);
   s.insert(10);
   s.insert(10);
   printSetInt(s);
}
int main(int argc, char *argv[])
{
   test();
   return 0;
}
10 10 10

unordered_set

unordered_set 和set 区别

底层数据结构: std::set 通常基于树结构(例如红黑树)实现,而 std::unordered_set 则基于哈希表实现。

元素顺序: 由于 std::set 是基于树实现的,所以它的元素是按顺序存储的,这意味着你可以使用迭代器来遍历元素并期望它们以某种顺序出现。相反,std::unordered_set 不保证元素的顺序,也就是说,你无法期望使用迭代器遍历时元素的顺序保持不变。

查找和插入操作的效率:由于 std::set 是基于树结构实现的,所以查找和插入操作的平均时间复杂度为 O(log n)。而 std::unordered_set 使用哈希表,所以查找和插入操作的平均时间复杂度为 O(1),但是这个 O(1) 性能依赖于哈希函数的工作方式以及哈希表的大小。

空间消耗:由于哈希表的使用,std::unordered_set 在空间上的消耗通常会比 std::set 大一些。

#include <iostream>  
#include <unordered_set>  
  
int main() {  
    std::unordered_set<int> us; // 声明一个整数无序集合  
  
    // 插入元素  
    us.insert(1);  
    us.insert(2);  
    us.insert(3);  
  
    // 查找元素  
    if (us.find(2) != us.end()) {  
        std::cout << "Element 2 is in the set" << std::endl;  
    }  
  
    // 删除元素  
    us.erase(2);  
  
    // 遍历元素  
    for (int x : us) {  
        std::cout << x << " ";  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

参考资料

http://c.biancheng.net/view/538.html

http://c.biancheng.net/view/7196.html

http://c.biancheng.net/view/7203.html

标签:std,容器,Set,const,迭代,STL,元素,set,集合
From: https://www.cnblogs.com/tian777/p/17980859

相关文章

  • STL-map/unordered_map映射
    STL-map/unordered_map映射目录STL-map/unordered_map映射1.构造初始化2.数据插入3.数据查找4.迭代器遍历5.删除和清空6.成员方法7.multimap8.unordered_map9.unordered_multimap10.底层原理11.总结12.参考资料键值对容器Map映射是一种类似于字典的数据结构。它是(键,值)对的序......
  • day09-集合
    集合(Set)是一种可变、无序的数据类型,集合中的元素是唯一的,不重复的诶?我们之前讲过的字典也是同样的可变,无序的数据类型,但是字典是键值对的存储形式,而集合不是1、初识集合集合使用大括号{}包裹着,元素之间使用逗号,分隔,集合中的元素可以是字符串、数字、元祖等其他任何不可变......
  • 批处理命令set截取字符详解
    在批处理中,set的功能有点繁杂:设置变量、显示环境变量的名及值、做算术运算、等待用户的输入、字符串截取、替换字符串,是我们常用的命令之一。在字符串截取方面,新手因为没能注意到偏移量的问题,很容易提取到错误的字符串,因此,特开此帖,详细解释set截取字符的用法。......
  • vscode windows CMakePresets.json
    vscode在windows下使用Ninja编译配置,使用VisualStudio编译环境。来源:CMakePresets.json参考:在VisualStudio中使用CMake预设进行配置和生成--示例文件CMakePresets.json{"version":2,"configurePresets":[{"name":"base","......
  • DataSet 读取/压缩 /解压
     //从数据库读取dataset,压缩写入wenjianMssqlHelperdb=newMssqlHelper(GlobalSetting.ConnectString);DataSetds=db.ExecuteDataSet("select*fromdim_goods");byte[]bytesData=GetBytesFromDataSet(ds......
  • Git必知必会基础(11):撤销操作(含reset)
     数据准备 说明:下面对file的操作,都可以用通配符gitadd<file>...比如:gitadd*.txt gitrestore<file>...比如:gitrestore--staged*.txt 修改文件(已提交过,文件已在本地仓库中)撤销:对工作区修改修改文件内容,可以看到master->origin的颜色变了 此时文件在工作区,根据上图提......
  • 集合进阶
    集合进阶集合体系结构​ List->ArrayList,LinkedList,Collection<​ Set->HashSet(->LinkedHashSet),TreeSet,List系列集合:添加的元素是有序,可重复,有索引.Set系列集合:添加的元素是无序,不重复,无索引.单列集合CollectionCollection是......
  • 【LeetCode1747. 应该被禁止的 Leetflex 账户】[MySQL 用户变量/Pandas]面向过程编程;
    目录题目地址MySQL代码等效pandas代码题目地址https://leetcode.cn/problems/leetflex-banned-accounts/description/MySQL代码witht1as(selectaccount_id,ip_address,loginastick,"login"asmytypefromLogInfounionallselectaccount_id,ip......
  • 传入一个List集合,返回分页好的数据
    传入一个List集合,返回分页好的数据。定义分页信息类:packagecom.cn.common;importjava.util.List;publicclassCommonPage<T>{privateintcurrentPage;privateinttotalPage;privateintpageSize;privatejava.util.List<T>list;publ......
  • 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象
    快速对比两个list数据集合此文引用csdn:https://blog.csdn.net/Zhu_daye/article/details/104798410小批量、快速对比两个list数据集合usingSystem.Linq.Expressions;Main();voidMain(){//对比源集合varsource=GenerateStudent(1,10000,1000);//......