集合操作总结日志

1.集合:  命名空间System.Collection

a) 集合常用操作: 增删改查 遍历 来自于IList接口

b) 就是一个能装一堆东西的容器. 而变量是一个能装一件东西的容器

i. ArrayList arr=new ArrayList(); 可变长度数组,使用类似于数组, 在添加第一个 元素 的时候 ,给数组扩容默认4个长度,再以后每一次添加元素超过数组长度时,就将实际添加数量赋给数组的长度.(比如数组长度现在是4,你要添加6个元素,这样一共为10个元素,数组这是不是扩容2次变为16的长度,而是只扩容一次,然后将元素的实际长度赋给数组的长度)

1. 属性:    Capacity:总容量  Count:数量

2. AddRange(ICollection );实现原理: 先扩容,然后调用 Array.CopyTo();方法 存入新数据.  

3. arr.Capacity=200; 创建一个200大小的数组 然后用新数组 替换 旧数组.

4. Remove() 是根据引用来删除元素的. Remove()中查找删除对象时的比较方法是Object里 默认的的Equals,比较方式是比较的 地址. 可以用户自定义比较类型 重写Remove()方法.

5. ToArray(); 直接获得ArrayList 中的数组 返回一个Object[]数组

6. Hashtable(key,value): Hashtable里的键不可以重复, 存储键的时候通过hashcode 查找存储地址,从而找到对应的值.

a) Hash算法:能够快速定位对象. 按照Hash码取值

b) ()当我们向Hashtable中Add元素时,元素储存在Hashtable的数组里的,下标是根据添加key的hash值算出来的(但因为hash值 取余 arr.Length(数组长度),所以肯定不会超过当前数组长度) !!!       Hashtable 储存元素时,是根据key的Hash值(hash值是通过GetHashCode()算出来的) %(取余)  数组长度 求出的一个下标值

 1.获得key的哈希值.

2.用哈希值取余数组长度 获得一个下标index

3.创建一个bucket对象,并设置3个成员值,添  加到index位置

4.注意:每个对象算出的Hashcode并不是唯一  的,有可能出现多个对象的Hashcode相同.

a) 解决机制: 1.再次hash一次. 2.桶装模式,将两个相同hashcode的对象装入同一位置.

5.当新增时,Hashtable里的容器数组已经满了,则以数组两倍的长度扩容.

(取) :  当我们从Hashtable取元素时(根据key来取),会根据key的hash值算出 对应要取元素的下标,并且比较元素里的key和当前要找的key参数的hash值是否相等,同时还要比较两个key的引用是都一致,如果都满足,则确定找到要取的元素

 

总结: 存 : 会根据key的 hash值 算出一个下标, 然后存

      取 : 会根据key的 hash值,算出一个下标, 然后取

取值得时候不需要遍历, 算出来下标直接取.

哈希表Hashtable实现原理:Hashtable中的实际数据都存储在一个内部的buket[]数组中,当用户希望取得Hashtable值得时候,Hashtable进行如下处理:

1.为了保证取值范围保存在 0--Buket.Length之间, 首先哈希算法根据键key 与数组长度Length 进行取模运算,算的实际数据的位置为: (f(K)=HashOf(K) % Array.Length)  至于这个哈希函数Hash(f)怎么算出来的,简单说,可以取关键字的AscII码,根据一定规则运算得到.

2.如果发现多个Key值得哈希值重复,如果发生多个 K 值的哈希值重复, 即 f(K1) = f(K2), 而 f(K1) 位置已经有数据占用了, Hashtable 采用的是 "开放定址法" 处理冲突, 具体行为是把 HashOf(K2) % Array.Length 改为 (HashOf(K2) + d(K2)) % Array.Length , 得出另外一个位置来存储关键字 K2 所对应的数据, d 是一个增量函数. 如果仍然冲突, 则再次进行增量, 依此循环直到找到一个 Array 中的空位为止. 将来查找 K2 的时候先搜索 HashOf(K2) 一档, 发现不是 K2, 那么增量 d(K2) 继续搜索, 直到找到为止. 连续冲突次数越多, 搜索次数也越多, 效率越低.

3.当插入的数据达到Hashtable容量的上限时,对 内部buket数组进行扩容(重新new一个更大的数组,然后把数据copy过去,最后将新数组的地址引用再付给旧数组)

4.随着插入的数据项逐渐增多, Hashtable 内部数组剩余的空位也越来越少下一次冲突的可能性也越来越多严重影响效率因此不能等到数组全部塞满后才进行扩容处理在 .NET 当插入数据个数和数组容量之比为 0.72 就开始扩容这个 0.72 称为装填因子 - Load Factor. 这是一个要求苛刻的数字某些时刻将装填因子增减 0.01, 可能你的 Hashtable 存取效率就提高或降低了 50%, 其原因是装填因子决定 Array.Length, Array.Length 影响 f(K) 的冲突几率进而影响了性能. 0.72 是 Microsoft 经过长期实验得出的一个比较平衡的值. (取什么值合适和 f(K) 的算法也有关, 0.72 不一定适合其他结构的哈希表)

5.Hashtable 的初始容量 Array.Length 至少为 11, 再次扩容的容量至少为 "不小于 倍于当前容量的一个质数". 这里举一个例子方便大家看看 Hashtable 是多么浪费空间.

假设以默认方式初始化一个 Hashtable, 依次插入 个值由于 8 / 0.72 > 11, 因此 Hashtable 自动扩容新的容量为不小于 11 * 2 的质数即 23. 所以实际仅有 个人吃饭却不得不安排一桌 23 个座儿的酒席十分奢侈避免如此铺张的途径是在初始化 Hashtable 时用带参构造方式直接指定 capacity 为 17, 但即便这样仍浪费了 个空间.

有心的读者经过计算可能会问为什么不是指定初始容量为 13, 13 是质数啊, 13 * 0.72 > 8 确实理想情况是这样但实际上由于动态计算并判断一个数是否质数需要大量时间故 .NET Hashtable 中的 capacity 值是内部预设的一个数列只能为 3, 7, 11, 17, 23... 所以十分遗憾. (只有当 Array.Length > 0x6DDA89 时动态计算扩容容量正常情况下我们不会存如此多的数据进去)

.NET 的 Hashtable 就是以这种方式来减少冲突以牺牲空间为代价换取读写速度假设你在实际开发中对内存空间要求很敏感譬如开发 ASP.NET 超大型 B/S 网站时就十分有必要检讨使用 Hashtable 的场景需求有的时候能否换个方式采取自定义 struct, 或者数组来高效实现呢?

 

 

 

转载于:https://www.cnblogs.com/zxp19880910/archive/2012/07/01/2571597.html

基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值