当前位置: 首页 > article >正文

了解一下C#的SortedSet

基础概念

SortedSet 是 C# 中的一个集合类型,位于 System.Collections.Generic 命名空间下。它是一个自动排序的集合,用于存储不重复的元素,并且会根据元素的自然顺序(默认排序)或自定义比较器进行排序,内部使用红黑树数据结构来维护元素的有序性。

  • 自动排序:每次添加或删除元素时,SortedSet 都会自动调整以保持元素的排序状态。
  • 不重复元素:SortedSet 不允许重复的元素。如果尝试添加一个已经存在的元素,该操作会被忽略。
  • 高效性:SortedSet 内部使用红黑树(一种自平衡二叉搜索树)实现,因此查找、插入和删除操作的时间复杂度为 O(log n)

主要特性

  • 自动保持元素排序:元素会根据其自然顺序(需实现 IComparable<T> 接口)或自定义比较器(IComparer<T>)排序。
  • 不包含重复元素:尝试添加已有元素时,Add 方法返回 false,集合保持不变。
  • 支持集合操作:提供并集、交集、差集等操作。
  • 支持子集视图:可以通过方法获取某个范围内的元素。
  • 快速访问边界值:提供 Min 和 Max 属性,快速获取最小和最大元素。

创建和初始化

基本创建方式

  • 使用默认比较器(升序)
    • // 使用默认比较器(升序)
      SortedSet<int> numbers = new SortedSet<int>();
  •  使用自定义比较器
    • // 使用自定义比较器
      SortedSet<string> names = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
  • 从现有集合创建
    • // 从现有集合创建
      int[] array = { 5, 2, 8, 1, 9 };
      SortedSet<int> sortedNumbers = new SortedSet<int>(array);
      // 结果:{1, 2, 5, 8, 9}
  • 使用集合初始化器
    • // 使用集合初始化器
      SortedSet<string> fruits = new SortedSet<string> { "Apple", "Banana", "Cherry" };

自定义比较器

  • 降序排列
    • // 降序排列
      SortedSet<int> descendingNumbers = new SortedSet<int>(Comparer<int>.Create((x, y) => y.CompareTo(x)));
  • 自定义对象排序
    • // 自定义对象排序
      public class Person : IComparable<Person>
      {public string Name { get; set; }public int Age { get; set; }public int CompareTo(Person other){if (other == null) return 1;return this.Age.CompareTo(other.Age); // 按年龄排序}
      }SortedSet<Person> people = new SortedSet<Person>();
  • 使用自定义比较器
    • // 或使用自定义比较器
      SortedSet<Person> peopleByName = new SortedSet<Person>(Comparer<Person>.Create((p1, p2) => string.Compare(p1.Name, p2.Name))
      );

基本操作

添加和删除元素

SortedSet<int> numbers = new SortedSet<int>();
  • 添加元素
    • // 添加元素
      bool added1 = numbers.Add(5);    // true,成功添加
      bool added2 = numbers.Add(3);    // true,成功添加
      bool added3 = numbers.Add(5);    // false,元素已存在Console.WriteLine(string.Join(", ", numbers)); // 输出:3, 5
  • 删除元素
    • // 删除元素
      bool removed = numbers.Remove(3); // true,成功删除
      numbers.Remove(10);  
  • 清空集合
    • // 清空集合
      numbers.Clear();

查询操作

SortedSet<int> numbers = new SortedSet<int> { 1, 3, 5, 7, 9 };
  • 检查元素是否存在
    • // 检查元素是否存在
      bool contains = numbers.Contains(5); // true
  • 获取元素数量
    • // 获取元素数量
      int count = numbers.Count; // 5
  • 检查是否为空
    • // 检查是否为空
      bool isEmpty = numbers.Count == 0; // false
  • 获取最小值和最大值
    • // 获取最小值和最大值
      int min = numbers.Min; // 1
      int max = numbers.Max; // 9

范围查询

  • 使用 GetViewBetween 方法获取指定范围内的元素子集
  • SortedSet<int> numbers = new SortedSet<int> { 1, 3, 5, 7, 9, 11, 13 };// 获取视图(不创建新集合)
    SortedSet<int> subset1 = numbers.GetViewBetween(3, 9);
    // 结果:{3, 5, 7, 9}SortedSet<int> subset2 = numbers.GetViewBetween(4, 10);
    // 结果:{5, 7, 9}// 视图会反映原集合的变化
    numbers.Add(6);
    Console.WriteLine(string.Join(", ", subset2)); // 输出:5, 6, 7, 9

    集合运算

    并集、交集、差集

SortedSet<int> set1 = new SortedSet<int> { 1, 2, 3, 4, 5 };
SortedSet<int> set2 = new SortedSet<int> { 4, 5, 6, 7, 8 };
  • 并集:UnionWith 将另一个集合的元素合并到 SortedSet 中。
    • // 并集(修改 set1)
      set1.UnionWith(set2);
      Console.WriteLine(string.Join(", ", set1)); // 1, 2, 3, 4, 5, 6, 7, 8
  • 交集:IntersectWith 保留与另一个集合的交集。
    • // 重新初始化
      set1 = new SortedSet<int> { 1, 2, 3, 4, 5 };// 交集(修改 set1)
      set1.IntersectWith(set2);
      Console.WriteLine(string.Join(", ", set1)); // 4, 5
  • 差集:ExceptWith 删除与另一个集合相交的元素。
    • // 重新初始化
      set1 = new SortedSet<int> { 1, 2, 3, 4, 5 };// 差集(set1 中有但 set2 中没有的元素)
      set1.ExceptWith(set2);
      Console.WriteLine(string.Join(", ", set1)); // 1, 2, 3
  • 对称差集:SymmetricExceptWith 两个集合中不共同拥有的元素
    • // 对称差集(两个集合中不共同拥有的元素)
      set1 = new SortedSet<int> { 1, 2, 3, 4, 5 };
      set1.SymmetricExceptWith(set2);
      Console.WriteLine(string.Join(", ", set1)); // 1, 2, 3, 6, 7, 8

集合关系判断

SortedSet<int> set1 = new SortedSet<int> { 1, 2, 3 };
SortedSet<int> set2 = new SortedSet<int> { 1, 2, 3, 4, 5 };
SortedSet<int> set3 = new SortedSet<int> { 2, 3 };
SortedSet<int> set4 = new SortedSet<int> { 6, 7 };
  • 子集判断
    • // 子集判断bool isSubset = set1.IsSubsetOf(set2);        // true
      bool isProperSubset = set1.IsProperSubsetOf(set2); // true
      bool isSuperset = set2.IsSupersetOf(set1);    // true
      bool isProperSuperset = set2.IsProperSupersetOf(set1); // true
  • 重叠判断
    • // 重叠判断
      bool overlaps = set1.Overlaps(set3);          // true(有共同元素2,3)
      bool overlaps2 = set1.Overlaps(set4);         // false(无共同元素)
  • 相等判断
    • // 相等判断
      bool areEqual = set1.SetEquals(set3);         // false

遍历和枚举

基本遍历

SortedSet<string> fruits = new SortedSet<string> { "Banana", "Apple", "Cherry" };
  • foreach 遍历(按排序顺序)
    • // foreach 遍历(按排序顺序)
      foreach (string fruit in fruits)
      {Console.WriteLine(fruit); // Apple, Banana, Cherry
      }
  • 使用枚举器
    • // 使用枚举器
      using (var enumerator = fruits.GetEnumerator())
      {while (enumerator.MoveNext()){Console.WriteLine(enumerator.Current);}
      }

反向遍历

SortedSet<int> numbers = new SortedSet<int> { 1, 3, 5, 7, 9 };// 反向遍历
foreach (int number in numbers.Reverse())
{Console.WriteLine(number); // 9, 7, 5, 3, 1
}

SortedSet 的优点和适用场景

优点

  • 自动保持元素排序,无需手动干预。
  • 确保元素唯一性,避免重复。
  • 高效的操作性能(O(log n))。
  • 支持集合操作和子集视图。

适用场景

  • 需要有序且不重复的元素集合,例如排行榜、时间线。
  • 实现优先级队列(尽管 C# 有 PriorityQueue<T>)。
  • 执行集合操作,如并集、交集等。

SortedSet 与其他集合类型的区别

  • 与 HashSet<T> 的区别
    • HashSet<T> 不保持顺序,查找时间为 O(1)。
    • SortedSet<T> 保持顺序,查找时间为 O(log n)。
  • 与 List<T> 的区别
    • List<T> 允许重复元素,不自动排序。
    • SortedSet<T> 不允许重复,自动排序。
  • 与 SortedList<TKey, TValue> 的区别
    • SortedList<TKey, TValue> 是键值对集合,键排序。
    • SortedSet<T> 是元素集合,元素本身排序。

相关文章:

了解一下C#的SortedSet

基础概念 SortedSet 是 C# 中的一个集合类型&#xff0c;位于 System.Collections.Generic 命名空间下。它是一个自动排序的集合&#xff0c;用于存储不重复的元素&#xff0c;并且会根据元素的自然顺序&#xff08;默认排序&#xff09;或自定义比较器进行排序&#xff0c;内…...

【平面波导外腔激光器专题系列】用于光纤传感的低噪声PLC外腔窄线宽激光器

----翻译自Mazin Alalusi等人的文章 摘要 高性价比的 1550 nm DWDM平面外腔 &#xff08;PLANEX&#xff09; 激光器是干涉测量、布里渊、LIDAR 和其他光传感应用的最佳选择。其线宽<3kHz、低相位/频率噪声和极低的RIN。 简介 高性能光纤分布式传感技术是在过去几年中开发…...

Pytorch里面多任务Loss是加起来还是分别backward? | Pytorch | 深度学习

当你在深度学习中进入“多任务学习(Multi-task Learning)”的领域,第一道关卡可能不是设计网络结构,也不是准备数据集,而是:多个Loss到底是加起来一起backward,还是分别backward? 这个问题看似简单,却涉及PyTorch计算图的构建逻辑、自动求导机制、内存管理、任务耦合…...

K8S Pod调度方法实例

以下是一篇面向企业用户、兼具通俗易懂和实战深度的 Kubernetes Pod 调度方法详解博文大纲与正文示例。全文采用“图文&#xff08;代码块&#xff09;并茂 问答穿插 类比”方式&#xff0c;模拟了真实终端操作及输出&#xff0c;便于读者快速上手。 一、引言 为什么要关注 P…...

【mindspore系列】- 算子源码分析

本文会介绍mindspore的算子源码结构、执行过程以及如何编写一个自定义的mindspore算子。 源码介绍 首先,我们先从https://gitee.com/mindspore/mindspore/ 官网中clone源代码下来。 clone好代码后,可以看到源码的文件夹结构如下(只列出比较重要的文件夹): docsmindspore…...

学习日记-day17-5.27

完成目标&#xff1a; 知识点&#xff1a; 1.日期相关类_Calendar日历类 常用方法:int get(int field) ->返回给定日历字段的值void set(int field, int value) :将给定的日历字段设置为指定的值void add(int field, int amount) :根据日历的规则,为给定的日历字段添加或…...

一种比较精简的协议

链接地址为&#xff1a;ctLink: 一个比较精简的支持C/C的嵌入式通信的中间协议。 本文采用的协议格式如下 *帧头 uint8_t 起始字节&#xff1a;0XAF\ *协议版本 uint8_t 使用的协议版本号&#xff1a;当前为0X01\ *负载长度 uint8_t 数据段内容长…...

网络常识:网线和光纤的区别

网络常识&#xff1a;网线和光纤的区别 一. 介绍二. 网线2.1 什么是网线&#xff1f;2.2 网线的主要类别2.3 网线的优势2.4 网线的劣势 三. 光纤3.1 什么是光纤&#xff1f;3.2 光纤的主要类别3.3 光纤的优势3.4 光纤的劣势 四. 网线 vs 光纤&#xff1a;谁更适合你&#xff1f…...

OpenCV CUDA模块图像过滤------创建一个 Scharr 滤波器函数createScharrFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于创建一个 Scharr 滤波器&#xff08;基于 CUDA 加速&#xff09;&#xff0c;用于图像的一阶导数计算。它常用于边缘检测任务中&#…...

html css js网页制作成品——HTML+CSS+js醇香咖啡屋网页设计(5页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

[特殊字符] 构建高内聚低耦合的接口架构:从数据校验到后置通知的分层实践

在现代企业系统开发中&#xff0c;接口结构设计的质量直接影响系统的稳定性、扩展性与可维护性。随着业务复杂度上升&#xff0c;单一层次的接口实现往往难以应对功能膨胀、事务一致性、后置扩展等需求。因此&#xff0c;我们提出一种面向复杂业务场景的接口分层模型&#xff0…...

brep2seq 源码笔记2

数学公式是什么def forward(self, noise_1, noise_2, real_z_pNone): if(real_z_p): z_p_ self.downsample(real_z_p) input_2 z_p_ noise_2 z_f self.gen_z_f(input_2) output real_z_p z_f else: …...

UE5 蓝图,隐藏一个Actor,同时隐藏它的所有子物体

直接用actor.sethideningame是不行的 要先找到根组件&#xff0c;这样就有覆盖子物体的选项了...

人工智能AI之机器学习基石系列 第 2 篇:数据为王——机器学习的燃料与预处理

专栏系列&#xff1a;《人工智能AI之机器学习基石》② 高质量的数据是驱动机器学习模型的强大燃料 &#x1f680; 引言&#xff1a;无米之炊与数据的重要性 在上一篇文章《什么是机器学习&#xff1f;——开启智能之门》中&#xff0c;我们一起揭开了机器学习的神秘面纱&…...

代码随想录算法训练营 Day58 图论Ⅷ 拓扑排序 Dijkstra

图论 题目 117. 软件构建 拓扑排序&#xff1a;给出一个有向图&#xff0c;把这个有向图转成线性的排序就叫拓扑排序。 当然拓扑排序也要检测这个有向图是否有环&#xff0c;即存在循环依赖的情况&#xff0c;因为这种情况是不能做线性排序的。所以拓扑排序也是图论中判断有向…...

实现单例模式的6种方法(Python)

目录 一. 基于模块的实现(简单&#xff0c;易用) 二. 重新创建时报错(不好用) 三. 只靠方法获取实例(不好用) 四. 类装饰器 五. 重写__new__方法 六. 元类 七. 总结 单例模式&#xff08;Singleton Pattern&#xff09;是一种设计模式&#xff0c;其核心目标是确保一个类…...

基于 STM32 的智慧农业温室控制系统设计与实现

摘要 本文提出一种基于 STM32 微控制器的智慧农业温室控制系统设计方案,通过集成多类型环境传感器、执行机构及无线通信模块,实现对温室内温湿度、光照、土壤湿度等参数的实时监测与自动调控。文中详细阐述硬件选型、电路连接及软件实现流程,并附关键代码示例,为智慧农业领…...

深度学习优化器相关问题

问题汇总 各类优化器SGDMomentumNesterovAdagardAdadeltaRMSpropAdam优化器 为什么Adam不一定最优而SGD最优的深度网络中loss除以10和学习率除以10等价吗L1,L2正则化是如何让模型变得稀疏的&#xff0c;正则化的原理L1不可导的时候该怎么办梯度消失和梯度爆炸什么原因&#xff…...

【免费】【无需登录/关注】度分秒转换在线工具

UVE Toolbox 功能概述 这是一个用于地理坐标转换的在线工具&#xff0c;支持两种转换模式&#xff1a; 十进制度 → 度分秒 度分秒 → 十进制度 使用方法 十进制度转度分秒 在"经度"输入框中输入十进制度格式的经度值&#xff08;例如&#xff1a;121.46694&am…...

常见的垃圾回收算法原理及其模拟实现

1.标记 - 清除&#xff08;Mark - Sweep&#xff09;算法&#xff1a; 这是一种基础的垃圾回收算法。首先标记所有可达的对象&#xff0c;然后清除未被标记的对象。 缺点是会产生内存碎片。 原理&#xff1a; 如下图分配一段内存&#xff0c;假设已经存储上数据了 标记所有…...

fpga-编程线性序列机和状态机

一、线性序列机和有限状态机和&#xff08;状态机-编程思想&#xff09;的原理 序列机是什么&#xff1a;用计数器对时钟个数计数&#xff0c;根据相应时钟周期下的单个周期时间和计数个数可以确定某个时刻的时间&#xff0c;确定时间后再需要时间点转换电平&#xff01; 采用…...

力扣面试150题--完全二叉树的节点个数

Day 51 题目描述 思路 根据完全二叉树的规律&#xff0c;完全二叉树的高度可以直接通过不断地访问左子树就可以获取&#xff0c;判断左右子树的高度: 1. 如果相等说明左子树是满二叉树, 然后进一步判断右子树的节点数(最后一层最后出现的节点必然在右子树中&#xff09; 2. 如…...

Qt 多线程环境下的全局变量管理与密码安全

在现代软件开发中&#xff0c;全局变量的管理和敏感信息的保护是两个重要的课题。特别是在多线程环境中&#xff0c;不正确的全局变量使用可能导致数据竞争和不一致的问题&#xff0c;而密码等敏感信息的明文存储更是会带来严重的安全隐患。本文将介绍如何在 Qt 框架下实现一个…...

内网映射有什么作用,如何实现内网的网络地址映射到公网连接?

在网络环境中&#xff0c;内网映射是一项重要的技术&#xff0c;它允许用户通过外部网络访问位于内部网络中的设备或服务。如自己电脑上的程序提供他人使用&#xff0c;或在家远程管理公司办公OA等涉及不同网络间的通信和数据交互。nat123作为一款老牌的内网映射工具&#xff0…...

BLIP3-o:一系列完全开源的统一多模态模型——架构、训练与数据集

摘要 在近期关于多模态模型的研究中&#xff0c;将图像理解与生成统一起来受到了越来越多的关注。尽管图像理解的设计选择已经得到了广泛研究&#xff0c;但对于具有图像生成功能的统一框架而言&#xff0c;其最优模型架构和训练方案仍有待进一步探索。鉴于自回归和扩散模型在…...

DNS解析流程入门篇

一、DNS 解析流程 1.1 浏览器输入域名 当在浏览器中输入 www.baidu.com 时&#xff0c;操作系统会按照以下步骤进行 DNS 解析&#xff1a; 检查本地 hosts 文件 &#xff1a;操作系统先检查本地的 /etc/hosts 文件&#xff0c;查看是否存在域名与 IP 地址的对应关系。如果找到…...

spring4第2课-ioc控制反转-依赖注入,是为了解决耦合问题

继续学习ioc控制反转&#xff0c; IOC&#xff08;Inversion of Control&#xff09;控制反转&#xff0c;也叫依赖注入&#xff0c; 目的是解决程序的耦合问题&#xff0c;轻量级spring的核心。 1.定义bean.xml <?xml version"1.0" encoding"UTF-8"…...

大模型系列22-MCP

大模型系列22-MCP 玩转 MCP 协议&#xff1a;用 Cline DeepSeek 接入天气服务什么是 MCP&#xff1f;环境准备&#xff1a;VScode Cline DeepSeek**配置 DeepSeek 模型&#xff1a;****配置 MCP 工具****uvx是什么&#xff1f;****安装 uv&#xff08;会自动有 uvx 命令&…...

【监控】Prometheus+Grafana 构建可视化监控

在云原生和微服务架构盛行的今天&#xff0c;监控系统已成为保障业务稳定性的核心基础设施。作为监控领域的标杆工具&#xff0c;Prometheus和Grafana凭借其高效的数据采集、灵活的可视化能力&#xff0c;成为运维和开发团队的“标配”。 一、Prometheus Prometheus诞生于2012…...

vscode里几种程序调试配置

标题调试python嵌入的c代码,例如 import torch from torch.utils.cpp_extension import loadtest_load load(nametest_load, sources[test.cpp],extra_cflags[-O0, -g],#extra_cflags[-O1],verboseTrue, ) a torch.tensor([1, 2, 3]) b torch.tensor([4, 5, 6]) result te…...