STL之set容器代码详解

news2024/11/16 3:32:57

1 基础概念

在这里插入图片描述

所有元素都会在插入时自动被排序

本质:

set/multiset属于关联式容器,底层结构是用二叉树实现。

set和multiset区别

set不允许容器中有重复的元素;

multiset允许容器中有重复的元素 。

2 代码示例

Talk is cheap, show me the code.

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

void printSet(const set<int>& ss)
{
	for (set<int>::const_iterator it = ss.begin(); it != ss.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

void printMultiset(const multiset<int>& ss)
{
	for (multiset<int>::const_iterator it = ss.begin(); it != ss.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

/*
构造:
set<T> st; //默认构造函数:
set(const set &st); //拷贝构造函数
赋值:
set& operator=(const set &st); //重载等号操作符
*/

void test01()
{
	set<int> s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);
	printSet(s1);

	set<int> s2(s1);
	printSet(s2);

	set<int> s3;
	s3 = s2;
	printSet(s3);

}

/*
大小和交换函数原型:
size(); //返回容器中元素的数目
empty(); //判断容器是否为空
swap(st); //交换两个集合容器
*/

void test02()
{
	set<int> s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);
	printSet(s1);

	if (s1.empty())
	{
		cout << "Empty" << endl;
	}
	else
	{
		cout << "Size: " << s1.size() << endl;
	}

	set<int> s2;
	s2.insert(100);
	cout << "交换前:" << endl;
	printSet(s1);
	printSet(s2);
	s1.swap(s2);
	cout << "交换后" << endl;
	printSet(s1);
	printSet(s2);
}

/*
插入和删除函数原型:
insert(elem); //在容器中插入元素。
clear(); //清除所有元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem); //删除容器中值为elem的元素。
*/

void test03()
{
	multiset<int> s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);
	s1.insert(40);
	s1.insert(40);
	s1.insert(40);
	printMultiset(s1);

	s1.erase(s1.begin());
	printMultiset(s1);

	s1.erase(40);
	printMultiset(s1);

	s1.erase(s1.begin(), s1.end());
	printMultiset(s1);

}

/*
查找和统计函数原型:
find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key); //统计key的元素个数
*/

void test04()
{
	multiset<int> s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);
	s1.insert(40);
	s1.insert(40);
	s1.insert(40);
	printMultiset(s1);

	multiset<int>::iterator pp = s1.find(20);
	if (pp != s1.end())
	{
		cout << "Find It: " << *pp << endl;
	}
	else
	{
		cout << "No this element" << endl;
	}

	cout << s1.count(40) << endl;

}

/*
set和multiset区别:
set不可以插入重复数据,而multiset可以
set插入数据的同时会返回插入结果,表示插入是否成功
multiset不会检测数据,因此可以插入重复数据
*/

void test05()
{
	set<int> s1;
	pair<set<int>::iterator, bool> ret = s1.insert(10);
	if (ret.second)
	{
		cout << "Insert OK" << endl;
	}
	else
	{
		cout << "Failed!" << endl;
	}

	ret = s1.insert(10);
	if (ret.second)
	{
		cout << "Insert OK" << endl;
	}
	else
	{
		cout << "Failed!" << endl;
	}

}

/*
pair对组创建
功能描述:
成对出现的数据,利用对组可以返回两个数据
两种创建方式:
pair<type, type> p ( value1, value2 );
pair<type, type> p = make_pair( value1, value2 );
*/

void test06()
{
	pair<string, int> pp1("zhangsan", 20);
	pair<string, int> pp2 = make_pair("lisi", 23);
	cout << pp1.first << " " << pp1.second << endl;
	cout << pp2.first << " " << pp2.second << endl;
}

/*
set容器排序:
set容器默认排序规则为从小到大,掌握如何改变排序规则
主要技术点:
利用仿函数,可以改变排序规则
*/

class Person
{
public:
	Person(string name, int age)
	{
		this->name = name;
		this->age = age;
	}

	string name;
	int age;
};

class compareP
{
public:
	bool operator()(const Person& p1, const Person& p2)const //VS2019需要在这个后面加一个const
	{
		return p1.age > p2.age;
	}
};

void test07()
{
	set<Person, compareP> s;

	Person p1("刘备", 23);
	Person p2("关羽", 27);
	Person p3("张飞", 25);
	Person p4("赵云", 21);

	s.insert(p1);
	s.insert(p2);
	s.insert(p3);
	s.insert(p4);

	for (set<Person, compareP>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << (*it).name << " " << (*it).age << endl;
	}
}

int main()
{
	test07();
	system("pause");
	return 0;
}

3 应用场景

C++的STL(标准模板库)中的set容器是一个有序的集合,其中的元素都是唯一的。它基于红黑树实现,提供了高效的插入、删除和查找操作。在实际项目中,set容器经常用于以下场景:

  1. 去重操作:
    当你需要从一组数据中去除重复元素时,set容器是一个理想的选择。由于set只允许存储唯一的元素,插入重复元素时不会导致集合中存在相同的值。这对于需要保持元素唯一性的情况非常有用。

    #include <set>
    #include <iostream>
    
    int main() {
        std::set<int> uniqueNumbers;
    
        uniqueNumbers.insert(10);
        uniqueNumbers.insert(20);
        uniqueNumbers.insert(10); // 这个插入操作不会改变集合,因为10已经存在
    
        for (const auto& num : uniqueNumbers) {
            std::cout << num << " ";
        }
    
        return 0;
    }
    
    
  2. 查找操作:set容器提供了快速的查找操作,因为底层实现是红黑树,保证了对数时间的查找复杂度。这对于需要快速检查元素是否存在于集合中的场景非常有帮助。

    #include <set>
    #include <iostream>
    
    int main() {
        std::set<std::string> names = {"Alice", "Bob", "Charlie"};
    
        std::string searchName = "Bob";
        if (names.find(searchName) != names.end()) {
            std::cout << searchName << " found in the set." << std::endl;
        } else {
            std::cout << searchName << " not found in the set." << std::endl;
        }
    
        return 0;
    }
    
    
  3. 有序遍历:
    由于set是有序的容器,可以很容易地实现按顺序遍历元素的需求。这在需要按照一定顺序处理元素的情况下非常有用。

    #include <set>
    #include <iostream>
    
    int main() {
        std::set<int> numbers = {5, 2, 8, 1, 9};
    
        for (const auto& num : numbers) {
            std::cout << num << " ";
        }
    
        return 0;
    }
    
    

这些是set容器在实际项目中的一些常见应用场景。根据具体需求,set还可以与其他STL容器和算法结合使用,提供更丰富的功能。

4 实际用例

假设你正在开发一个简单的单词计数应用,需要统计一段文本中不同单词的出现次数。在这种情况下,set容器可以很方便地帮助你实现去重操作,确保每个单词只被计数一次。以下是一个使用set的小demo:

#include <iostream>
#include <set>
#include <map>
#include <string>
#include <sstream>

int main() {
    // 输入的文本
    std::string text = "This is a sample text with some repeated words. This is just a demo.";

    // 使用set进行去重操作
    std::set<std::string> uniqueWords;

    // 使用map来记录单词出现的次数
    std::map<std::string, int> wordCount;

    // 通过istringstream分割文本并处理单词
    std::istringstream iss(text);
    std::string word;
    while (iss >> word) {
        // 将单词插入set,确保唯一性
        uniqueWords.insert(word);

        // 更新单词计数
        wordCount[word]++;
    }

    // 打印去重后的单词
    std::cout << "Unique words in the text:" << std::endl;
    for (const auto& uniqueWord : uniqueWords) {
        std::cout << uniqueWord << " ";
    }
    std::cout << std::endl;

    // 打印每个单词的出现次数
    std::cout << "Word count:" << std::endl;
    for (const auto& pair : wordCount) {
        std::cout << pair.first << ": " << pair.second << " times." << std::endl;
    }

    return 0;
}

在这个例子中,set容器确保了每个单词的唯一性,而map用于记录每个单词的出现次数。通过使用set,我们可以方便地获取文本中的唯一单词列表,而不必担心重复计数。这展示了set在项目中用于处理数据唯一性的优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1502398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GO语言接入支付宝

GO语言接入支付宝 今天就go语言接入支付宝写一个教程 使用如下库&#xff0c;各种接口较为齐全 "github.com/smartwalle/alipay/v3"先简单介绍下加密&#xff1a; 试想&#xff0c;当用户向支付宝付款时&#xff0c;若不进行任何加密&#xff0c;那么黑客就可以任…

【牛客】VL76 任意奇数倍时钟分频

描述 编写一个模块&#xff0c;对输入的时钟信号clk_in&#xff0c;实现任意奇数分频&#xff0c;要求分频之后的时钟信号占空比为50%。模块应包含一个参数&#xff0c;用于指定分频的倍数。 模块的接口信号图如下&#xff1a; 要求&#xff1a;使用Verilog HDL语言实现&#…

2024最新版CleanMyMac X 4.15.1 Crack+激活码下载

CleanMyMac X 为您喜爱的事物腾出空间。 CleanMyMac 具有一系列巧妙的新功能&#xff0c;可让您安全、智能地扫描和清理整个系统、删除大型未使用的文件、减小 iPhoto 图库的大小、卸载不需要的应用程序或修复开始工作不正常的应用程序、管理所有应用程序您可以从一个地方进行扩…

html css 导航栏 2

鼠标划过会向上移动改变颜色 html文件 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>导航栏</title><link rel"stylesheet" href"css/dhl1.css" /></head><body><div …

分销商城微信小程序:用户粘性增强,促进复购率提升

在数字化浪潮的推动下&#xff0c;微信小程序作为一种轻便、高效的移动应用形式&#xff0c;正成为越来越多企业开展电商业务的重要平台。而分销商城微信小程序的出现&#xff0c;更是为企业带来了前所未有的机遇。通过分销商城微信小程序&#xff0c;企业不仅能够拓宽销售渠道…

揭秘税务信息接口:解读企业税务登记与纳税情况

导语&#xff1a; 随着社会经济的发展&#xff0c;税收对于国家财政收入的重要性不言而喻。税务登记信息和纳税情况对于企业和个人来说至关重要。在这个背景下&#xff0c;税务信息接口应运而生&#xff0c;为我们提供了便捷的查询途径。本文将以挖数据平台提供的税务信息接口…

【IPC】管道通信【命名管道】

文章目录 1.管道小总结2.命名管道2.1认识命名管道2.2命名管道的应用小场景2.3模拟命名管道1.Lod.hpp2.common.hpp3.server.cxx4.client.cxx 3.管道代码总结 1.管道小总结 linux-manualshouce 在Linux中&#xff0c;manual手册的编号用于区分手册的不同部分。这些编号通常用于ma…

个人商城系统开源(发送手机验证码!)

原文地址&#xff1a;个人商城系统开源&#xff08;发送手机验证码&#xff01;&#xff09; - Pleasure的博客 下面是正文内容&#xff1a; 前言 由于近期实在没有什么话题可写和一些有趣的项目教程可以分享。所以我只能决定将我自己亲手编写的一个迷你迷你商城系统进行开源…

3 模型评估

3 模型评估 在测试AI系统中的模型训练和评估阶段,需要使用准备好的数据集对AI模型进行训练和评估。在训练过程中,应该对模型进行监控和调整,以确保模型的准确性和效果。在评估过程中,需要使用测试数据集对模型进行测试,以验证模型的准确性和效果。模型的评估也分为离线评…

通过一篇文章带你玩转git和GitHub

Git和Github的基本用法 前言一、Git和Github的基本用法背景下载安装安装 git for windows安装 tortoise gitgit安装过程中的一些选项 tortoise git汉化教程下载tortoise git汉化安装包安装tortoise git汉化安装包 三、使用 Github 创建项目注册账号创建项目下载项目到本地 四、…

视频批量混剪剪辑,批量剪辑批量剪视频,探店带货系统,精细化顺序混剪,故事影视解说,视频处理大全,精细化顺序混剪,多场景裂变,多视频混剪

前言 工具的产生源于dy出的火山引擎的云视频混剪制作是按分钟数收费的&#xff0c;这个软件既能实现正常混剪也能避免二次收费。属于FFMPEG合成的。 欢迎大家给一些好的建议和功能&#xff0c;回复可见&#xff0c;附加了一些天卡&#xff0c;周卡&#xff0c;请大家不要一人占…

【C++】函数模板和类模板

目录 1.泛型编程 2.函数模板 2.1函数模板的定义格式 2.2函数模板的实例化 2.3函数模板参数的匹配原则 3.类模板 3.1类模板的定义格式 3.2类模板的实例化 3.3模板的分离编译 1.泛型编程 泛型编程&#xff1a;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段…

新一代 Git 工具,AI 赋能!深度集成、简化操作 | 开源日报 No.194

gitbutlerapp/gitbutler Stars: 7.2k License: NOASSERTION gitbutler 是一个基于 Git 的版本控制客户端。旨在为现代工作流程构建一个全新的 Git 分支管理工具。 虚拟分支&#xff1a;可以同时在多个分支上工作&#xff0c;而无需不断切换分支简化提交管理&#xff1a;通过拖…

如何转行成为产品经理?

转行NPDP也是很合适的一条发展路径&#xff0c;之后从事新产品开发相关工作~ 一、什么是NPDP&#xff1f; NPDP 是产品经理国际资格认证&#xff0c;美国产品开发与管理协会&#xff08;PDMA&#xff09;发起的&#xff0c;是目前国际公认的唯一的新产品开发专业认证&#xff…

stm32普通定时器脉冲计数(发送固定脉冲个数),控制步进电机驱动器

拨码开关设置驱动器&#xff0c;细分 方法思路&#xff1a;用通用定时器TIM2&#xff0c;1ms产生一次中断&#xff1b;在中断里做IO反转&#xff1b; 发送10个脉冲信号

Docker部署SimpleMindMap结合内网穿透实现公网访问本地思维导图

文章目录 1. Docker一键部署思维导图2. 本地访问测试3. Linux安装Cpolar4. 配置公网地址5. 远程访问思维导图6. 固定Cpolar公网地址7. 固定地址访问 SimpleMindMap 是一个可私有部署的web思维导图工具。它提供了丰富的功能和特性&#xff0c;包含插件化架构、多种结构类型&…

【漏洞复现】大华ICC智能物联综合管理平台token弱口令漏洞

Nx01 产品简介 大华智能物联综合管理平台 iConnection Center&#xff08;以下简称&#xff1a;ICC平台&#xff09;&#xff0c;是一套基于智能物联的综合业务管理平台软件&#xff0c;具备强大的后台服务能力&#xff0c;配套了B/S管理员端、C/S客户端、移动APP终端、小程序等…

Java的Writer类详解

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

Tomcat容器经常重启问题排查

报错代码: INFO [Catalina-utility-2] org.apache.catalina.core.StandardContext.reload Reloading Context with name [] has started1.查看内存占用情况:top 可以发现java线程正常情况下占用高达24%的内存资源 2.继续排查:top -Hp 29580 可以发现主要有子线程Catalina-ut…

汉服|高校汉服租赁网站|基于Springboot的高校汉服租赁网站设计与实现(源码+数据库+文档)

高校汉服租赁网站目录 目录 基于Springboot的高校汉服租赁网站设计与实现 一、前言 二、系统设计 三、系统功能设计 1、汉服信息管理 2、汉服租赁管理 3、公告管理 4、公告类型管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选…