C#学习笔记--实现一个可以重复权重并且能够自动排序的容器--MultiplySortedSet

news2024/9/23 3:30:13

目录

    • 前言
    • SortedSet
      • C#自带类型
      • 自定义类
      • SortedSet权值重复
    • 需求
    • 自定义容器 -- MultiplySortedSet
      • 核心实现思路
    • MultiplySortedSet 使用
      • C#自带类型
      • 自定义类

前言

最近需要在C#中实现一个功能
有一个容器,该容器能自动对里面的元素进行排序,类似C++的优先队列,也就是堆。
但是查询了C#提供的一些容器,只有 SortedSet 和我们的需求很符合。

SortedSet

其实就是一个可以自动排序的容器

我们在Unity下使用看看

C#自带类型

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SortedSetTest : MonoBehaviour
{
    private void Awake()
    {
        SortedSet<int> ssi = new SortedSet<int>();
        ssi.Add(10);
        ssi.Add(1);
        ssi.Add(5);
        ssi.Add(-1);

        foreach (var item in ssi)
        {
            print(item);
        }
    }
}

在这里插入图片描述

自定义类

public class Student : IComparable<Student>
{
    private int id;
    public Student(int id_in)
    {
        id = id_in;
    }
    public int CompareTo(Student other)
    {
        return id.CompareTo(other.id);
    }
    public override string ToString()
    {
        return $"Student ID {id}";
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SortedSetTest : MonoBehaviour
{
    private void Awake()
    {
        SortedSet<Student> sss = new SortedSet<Student>();
        sss.Add(new Student(10));
        sss.Add(new Student(1));
        sss.Add(new Student(5));
        sss.Add(new Student(-1));

        foreach (var item in sss)
        {
            print(item);
        }
    }
}

在这里插入图片描述

SortedSet权值重复

我们能看出来它可以自动进行排序

但是如果权值重复了该怎么办?我们来试试看

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SortedSetTest : MonoBehaviour
{
    private void Awake()
    {
        SortedSet<int> ssi = new SortedSet<int>();
        ssi.Add(10);
        ssi.Add(1);
        ssi.Add(1);
        ssi.Add(-1);

        foreach (var item in ssi)
        {
            print(item);
        }
    }
}

在这里插入图片描述
我们发现相同的 1 并没有被加入到集合中,这也算是 SortedSet 的特性,毕竟是 Set 嘛。

需求

但是我们现在需要的是重复的权值也可以保存下来,并且进行排序。那该怎么办呢?
这里我并没有找到C#自带的符合需求的容器(C++有优先队列),所以我们这里自定义一个容器来实现。

自定义容器 – MultiplySortedSet

多说无益,直接上代码。

using System;
using System.Collections;
using System.Collections.Generic;

namespace Util
{
    //排序方法
    public enum MultiplySortedType
    {
        Ascending,      //升序
        Descending,     //降序
    }

    public class MultiplySortedSet<T> : IEnumerable<T> where T : IComparable<T>
    {
        private SortedSet<KeyValuePair<T, Guid>> _elements;
        private Dictionary<T, Guid> _elementIds;

        public MultiplySortedSet(IComparer<KeyValuePair<T, Guid>> comparer = null)
        {
            //默认为升序
            if(comparer == null)
            {
                comparer = new ComparerAscending();
            }
            _elements = new SortedSet<KeyValuePair<T, Guid>>(comparer);
            _elementIds = new Dictionary<T, Guid>();
        }

        public MultiplySortedSet(MultiplySortedType sortedType)
        {
            IComparer<KeyValuePair<T, Guid>> comparer = null;
            switch (sortedType)
            {
                case MultiplySortedType.Ascending:
                    comparer = new ComparerAscending();
                    break;
                case MultiplySortedType.Descending:
                    comparer = new ComparerDescending();
                    break;
            }
            _elements = new SortedSet<KeyValuePair<T, Guid>>(comparer);
            _elementIds = new Dictionary<T, Guid>();
        }

        public void Add(T element)
        {
            Guid guid = Guid.NewGuid();
            _elements.Add(new KeyValuePair<T, Guid>(element, guid));
            _elementIds[element] = guid;
        }

        public void Remove(T element)
        {
            //如果Ids存在,则说明_elements里面肯定有该元素
            //RemoveWhere是为了删除单一元素
            //因为不同T对象的Compare可能相同,但是Guid肯定不同
            if (_elementIds.ContainsKey(element))
            {
                _elements.RemoveWhere(x => x.Key.CompareTo(element) == 0 && x.Value.CompareTo(_elementIds[element]) == 0);
                _elementIds.Remove(element);
            }
        }

        public bool Contains(T element)
        {
            return _elementIds.ContainsKey(element);
        }

        public int Count
        {
            get { return _elements.Count; }
        }

        public IEnumerator<T> GetEnumerator()
        {
            foreach (var element in _elements)
            {
                yield return element.Key;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        private class ComparerAscending : IComparer<KeyValuePair<T, Guid>>
        {
            public int Compare(KeyValuePair<T, Guid> x, KeyValuePair<T, Guid> y)
            {
                //先调用T的Compare,如果相等就比较Guid
                int result = x.Key.CompareTo(y.Key);
                if (result == 0)
                {
                    result = x.Value.CompareTo(y.Value);
                }
                return result;
            }
        }

        private class ComparerDescending : IComparer<KeyValuePair<T, Guid>>
        {
            public int Compare(KeyValuePair<T, Guid> x, KeyValuePair<T, Guid> y)
            {
                //先调用T的Compare,如果相等就比较Guid
                int result = y.Key.CompareTo(x.Key);
                if (result == 0)
                {
                    result = x.Value.CompareTo(y.Value);
                }
                return result;
            }
        }
    }
}

核心实现思路

其实核心思路就一点,多做一层封装,当对象权重相等时,比较另外一个值。

  1. 首先 SortedSet 不可以存储相同权重,所以我们这里使用 KeyValuePair 来封装一层。

Key为排序的对象,这里就拿泛型T替代。
Value存在的意义就是,当某些T对象权重相等时,拿Value的值来作比较。也就是说每一个相等权重的对象T的Value一定要不一样。所以这里Value可以拿System.Guid来做。

  1. 自定义一个 Comparer ,如果Key值相等,那么就比较Value值。

MultiplySortedSet 使用

C#自带类型

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Victor_Util;

public class Test : MonoBehaviour
{

    private void Awake()
    {
        MultiplySortedSet<int> vs = new MultiplySortedSet<int>();
        vs.Add(9);
        vs.Add(1);
        vs.Add(1);
        vs.Add(1);
        vs.Add(-5);
        vs.Add(100);
        foreach (var item in vs)
        {
            print(item);
        }
        
    }
}

在这里插入图片描述

自定义类

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Victor_Util;

public class Test : MonoBehaviour
{

    private void Awake()
    {
        MultiplySortedSet<Student> vs2 = new MultiplySortedSet<Student>();
        vs2.Add(new Student(9));
        vs2.Add(new Student(1));
        vs2.Add(new Student(1));
        vs2.Add(new Student(1));
        vs2.Add(new Student(-5));
        vs2.Add(new Student(100));
        foreach (var item in vs2)
        {
            print(item);
        }

    }
}

在这里插入图片描述

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

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

相关文章

fast中user_id如何显示user表中的名称_关联模型

问题&#xff1a;编辑框内的user_id显示的是nickname 列表里如何显示nickname或是username 解决方案如下&#xff1a; 需要更改3个地方&#xff0c;控制器&#xff0c;模型&#xff0c;js文件 1.控制器index list($where, $sort, $order, $offset, $limit) $this->build…

ES6D: 利用对称性进行高效的6D姿态检测

利用对称性进行高效的6D姿态检测 本文参考自CVPR2022的这篇文章&#xff1a;ES6D: A Computation Efficient and Symmetry-Aware 6D Pose Regression Framework Github链接为&#xff1a;https://github.com/GANWANSHUI/ES6D 介绍 在6D姿态检测中&#xff0c;一些具备对称性的…

米哈游的春招实习面经,问的很基础

米哈游的春招实习面经&#xff0c;主要考察了java操作系统mysql网络&#xff0c;这四个方面。 面试流程&#xff0c;共1小时&#xff0c;1min自我介绍&#xff0c;20min写题&#xff0c;剩下问题基础知识。 Java String&#xff0c;StringBuilder&#xff0c; StringBuffer区…

注意力模型

如果拿机器翻译来解释这个分心模型的Encoder-Decoder框架更好理解&#xff0c;比如输入的是英文句子&#xff1a;Tom chase Jerry&#xff0c;Encoder-Decoder框架逐步生成中文单词&#xff1a;“汤姆”&#xff0c;“追逐”&#xff0c;“杰瑞”。 在翻译“杰瑞”这个中文单词…

低代码/0代码(无代码)开发平台如何选型?这篇文章告诉你

随着数字化转型的加速&#xff0c;越来越多的企业开始寻求低代码或零代码开发平台来加速应用程序的开发和部署。选对合适的平台是至关重要的&#xff0c;因为这将决定企业能否在数字化转型中保持竞争优势。 市面上的低/零代码平台五花八门&#xff0c;在选型的时候需要考虑哪些…

搭建本地仓库源

一、如何搭建仓库源 之前讲了定制ISO的方法&#xff1a;使用chroot定制系统&#xff0c;但有时候我们想自定义的安装包不在上游的仓库源中&#xff0c;在我们本地应该怎么办呢&#xff1f;如果我们将deb包拷贝到iso目录再安装有点过于麻烦了&#xff0c;而且还可能需要手动处理…

Linux 常见命令与常见问题解决思路

Linux 常见命令 Linux 基础命令目录相关查看文件&#xff08;日志&#xff09;查看普通的文件查看压缩的文件 解压压缩Linux 系统调优topvmstatpidstatps vi/vim 编辑文件查找文件属性相关定时任务scp 复制文件和目录awk 分隔cutsort 与 uniq常见问题处理思路CPU 高系统平均负载…

数组存储与指针学习笔记(一)数据类型与存储、数据对齐、数据移植、typedef

数据类型与存储 一、数据类型与存储1.1 大端模式与小端模式1.2 有符号数和无符号数1.3 数据溢出1.4 数据类型转换 二、数据对齐2.1 为什么非要地址对齐2.2 结构体对齐2.3 联合体对齐 三、数据的可移植性四、Linux内核中的size_t类型五、typedef5.1 typedef的基本用法5.2 typede…

python操作集合

# 集合 l{1,2,1} print(l) sset(range(5)) print(s)# 判断in 或 not in print(5 not in l) # 集合元素新增操作 l.add(4) l.update(1,3,6) print(l) l.update((1,3,5)) l.update([4,4,6]) # 删除集合元素 l.remove(2) l.discard(2) # 无目的的删除 自己不带参数 l.pop() l.cl…

【跟着陈七一起学C语言】今天总结:C预处理器和C库

友情链接&#xff1a;专栏地址 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的错误&#x…

大语言模型(LLM)和基于人类反馈的强化学习(RLHF)

只需三步&#xff0c;构建你的LLM 预训练语言模型 L L M S S L LLM^{SSL} LLMSSL&#xff08;self-supervised-learning)(指令)监督微调预训练模型 L L M S F T LLM^{SFT} LLMSFT&#xff08;supervised-fine-tuning)基于人类反馈的强化学习微调 L L M R L LLM^{RL} LLMRL&…

K8s常用命令

Namespace 默认情况下&#xff0c;kubernetes集群中的所有的Pod都是可以相互访问的。但是在实际中&#xff0c;可能不想让两个Pod之间进行互相的访问&#xff0c;那此时就可以将两个Pod划分到不同的namespace下。kubernetes通过将集群内部的资源分配到不同的Namespace中&#…

猪场规模怎样划分?类型都有哪些?

养猪场按照经营方式分为大中小猪场&#xff08;猪场规模&#xff09;和集团猪场。集团猪场是指集团化发展与管理的养猪企业&#xff0c;或者简称为集团化养猪企业&#xff0c;重点在于“集团化”。猪场规模则是按照年出栏数量划分。 小规模猪场&#xff1a;年出栏3000头以下&a…

加密芯片在GCP系统的应用方案

物联网&#xff08;IoT&#xff09;设备正在迅速发展&#xff0c;越来越多的设备连接到互联网并与其他设备进行通信。这使得设备的安全变得更加重要&#xff0c;因为它们可能会暴露敏感的数据和功能。Google Cloud IoT Core&#xff08;GCP&#xff09;是一个完全托管的服务&am…

Easydict 简洁易用的翻译词典,带你轻松优雅地查找单词或翻译文本。

Easydict Easydict 是一个简洁易用的翻译词典 macOS App&#xff0c;能够轻松优雅地查找单词或翻译文本。Easydict 开箱即用&#xff0c;能自动识别输入文本语言&#xff0c;支持输入翻译&#xff0c;划词翻译和 OCR 截图翻译&#xff0c;可同时查询多个翻译服务结果&#xff…

喜报丨迪捷软件荣获浙江省专精特新荣誉称号

近日&#xff0c;根据工业和信息化部《优质中小企业梯度培育管理暂行办法》&#xff08;工信部企业〔2022〕63号&#xff09;和《浙江省经济和信息化厅关于印发浙江省优质中小企业梯度培育管理实施细则&#xff08;暂行&#xff09;的通知》&#xff08;浙经信企业〔2022〕197号…

光耦合器的输入电路及重要参数

光耦合器是一种通过使用光能将输入控制信号耦合到输出或负载的器件&#xff0c;其方式使得输入信号和负载&#xff08;输出&#xff09;之间的电气隔离也保持不变。光耦合器的基本功能是通过光能耦合输入和输出电路&#xff08;因此称为光耦合器&#xff09;&#xff0c;并在输…

Monaco Editor编辑器教程(三十):将vue文件作为一种编程语言集成到monaco editor中,实现vue组件的语法,标签高亮。

前言 最近在使用gitlab的web ide时发现当编写一个 vue组件时,文件的后缀名为.vue。在编辑器的右上角会显示当前的编程语言时vue,并且高亮语法或标签,格式化,折叠都表现很优秀。但是其实monaco是不支持vuejs的,作为一名前端开发者,我们有时需要在monaco编辑器中编写vue组…

操作系统学习02

&#xff01;&#xff01;&#xff01;由于感冒和出去玩&#xff0c;好几天没学这些计算机基础知识了&#xff01;&#xff01;&#xff01; 抓紧跟上嘿嘿嘿 1、内存管理主要做了什么 操作系统的内存管理非常重要&#xff0c;主要负责下面这些事情&#xff1a; 内存的分配与…

Windows服务器配置开机自启动

有两种简单实现的方式。 第一种&#xff0c;直接将可执行文件或脚本的快捷方式放置到 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 这个文件夹里&#xff0c;服务器在启动的时候会自动执行。 第二种&#xff0c;配置为windows系统服务 利用winsw来将可…