用js来实现那些数据结构10(集合02-集合的操作)[通俗易懂]

前一篇文章我们一起实现了自定义的set集合类。那么这一篇我们来给set类增加一些操作方法。那么在开始之前,还是有必要解释一下集合的操作有哪些。便于我们更快速的理解代码。1、并集:对于给定的两个集合,

大家好,又见面了,我是你们的朋友全栈君。

  前一篇文章我们一起实现了自定义的set集合类。那么这一篇我们来给set类增加一些操作方法。那么在开始之前,还是有必要解释一下集合的操作有哪些。便于我们更快速的理解代码。

  1、并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。注意,集合中不会有重复的值。  

  2、交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合。

  3、差集:对于给定的集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。简单来说就是我有你没有的元素。

  4、验证一个给定集合是否是另一个集合的子集。

  这里我们就不详细的再赘述一遍集合操作的数学计算方法了。有兴趣或者忘记了的小伙伴可以百度一下。那么咱们就正式开始集合的操作方法。

一、并集

//并集操作
this.union = function (otherSet) {
    //存储两个集合元素的新集合,后面我们会把它作为返回值返回。
    let unionSet = new Set(); //values为当前set的数组列表 let values = this.values(); //循环加入 for(let i = 0; i < values.length; i++) { unionSet.add(values[i]); } //重新复制values values = otherSet.values(); //把otherSet的值循环存入unionSet,由于我们的add不会加入重复的值,自然在unionSet中就不会出现重复的值 for(let i = 0; i < values.length; i++) { unionSet.add(values[i]); } return unionSet; }

  我们发现,其实并集的操作十分简单,就是声明一个新的set,然后通过循环两个setA和setB中的值存入新的unionSet中就可以了。一点都不复杂

let setA = new Set();
setA.add(1); setA.add(2); setA.add(3); let setB = new Set(); setB.add(3); setB.add(4); setB.add(5); setB.add(6); let unionAB = setA.union(setB); console.log(unionAB.values());// [1, 2, 3, 4, 5, 6]

二、交集

//交集操作
this.intersection = function (otherSet) {
  let intersectionSet = new Set(); let values = this.values(); for (let i = 0; i < values.length; i++) { if(otherSet.has(values[i])) { intersectionSet.add(values[i]) } } return intersectionSet; }

  交集操作其实十分简单,一句话就是检查setA中的元素是否在setB中也有,如果有那么久存入intersectionSet中。就跟我们要查找两个数组中是否有相同的元素是一个道理。

let setC = new Set();
setC.add(5); setC.add(6); setC.add(7); let setD = new Set(); setD.add(5); setD.add(7); setD.add(4); setD.add(8); let intersectionSetCD = setC.intersection(setD); console.log(intersectionSetCD.values());//[5,7]

三、差集

//差集操作
this.difference = function (otherSet) {
  let differenceSet = new Set(); let values = this.values(); for (let i = 0; i < values.length; i++) { //只是比交集操作这里的判断改成了非(!)而已 if(!otherSet.has(values[i])) { differenceSet.add(values[i]) } } return differenceSet; }

  差集的操作和并集的操作十分类似。并集是需要两个集合中都存在的元素(你有我也有),而差集是存在于setA中但是不存在于setB中(你有我没有)。

  所以我们只需要稍微更改一下交集的代码就可以了。

let setM = new Set();
setM.add(5); setM.add(6); setM.add(7); let setN = new Set(); setN.add(5); setN.add(7); setN.add(4); setN.add(8); let differenceSetMN = setM.difference(setN); console.log(differenceSetMN.values());//[6]

四、子集

//子集操作
this.subset = function (otherSet) {
    if(this.size() > otherSet.size()) { return false; } else { let values = this.values(); for (let i = 0; i < values.length; i++) { if(!otherSet.has(values[i])) { return false; } } return true; } }

  其实子集操作也没什么好解释的,只是要注意的是如果setA的子集是setB,那么setA的元素个数是一定大于或等于setB的。否则setB就不可能是setA的子集。所以我们在最开始就判断元素的size是否符合这个定义。

  那么如果符合,我们在遍历整个setB的元素,判断在setA中是否存在,只要有不存在的就直接返回false,如果遍历结束都存在,那么才返回true。

let setX = new Set();
setX.add(1); setX.add(2); let setY= new Set(); setY.add(1); setY.add(2); setY.add(3); let setZ= new Set(); setZ.add(2); setZ.add(3); setZ.add(4); console.log(setX.subset(setY));//true console.log(setX.subset(setZ));//false

  这里我们就介绍完了集合的操作,是不是十分简单。那么接下来我们来看看ES6原生的set类是什么样子的。

ES6原生Set类

  我们先来看看原生set类的简单例子:

let set = new Set();
set.add(1); console.log(set.values());//SetIterator {1} set.add(2); console.log(set.has(1));//true console.log(set.size)//2 console.log(set.delete(1));//true console.log(set.size)//1 console.log(set.has(1));//false console.log(set.has(2));//true

  原生Set类拥有has()、add()、delete()、clear()等方法。也拥有values()、keys()、entries()、forEach()等遍历方法,还拥有一个size属性。这里不会详细的介绍每一个属性方法,想要深入学习大家可以自行去查阅。

  那么我们看看如何用原生Set类来操作集合。

let setA = new Set();
setA.add(1); setA.add(2); setA.add(3); let setB = new Set(); setB.add(2); setB.add(3); setB.add(4); //模拟并集操作 let unionAb = new Set(); //其实跟我们自定义并集操作的原理是一样的,分别遍历两个集合并把其元素加入到unionAb中 //for...of 这种操作也是ES6的循环遍历方法。 for (let x of setA) unionAb.add(x); for (let x of setB) unionAb.add(x); console.log(unionAb.values())//SetIterator {1, 2, 3, 4} //模拟交集操作 //模拟交集操作需要创建一个辅助函数,来生成包含setA和setB都有的元素的新集合。 let intersetion = function (setA,setB) { let intersetionSet = new Set(); for(let x of setA) { if(setB.has(x)) { intersetionSet.add(x); } } return intersetionSet; } let intersetionAb = intersetion(setA,setB); console.log(intersetionAb.values())//SetIterator {2, 3} //模拟差集操作 //同样的,跟交集操作极为类似,只是判断条件刚好相反罢了 let difference = function (setA,setB) { let differenceSet = new Set(); for(let x of setA) { if(!setB.has(x)) { differenceSet.add(x); } } return differenceSet; } let differenceAb = difference(setA,setB); console.log(differenceAb.values())//SetIterator {1}

  在写完了ES6原生Set类模拟集合操作的时候,我们发现跟我们自定义的集合操作方法极为相似。只是我们使用了ES6原生的接口罢了。大家可以尝试着对比一下这两种类型的代码。加深印象。

  到这里集合就介绍完毕了。回顾一下代码,我们发现其实集合的各种操作方法在我们的实际工作中也是经常应用到的,只是我们在用数组操作,并没有十分的去注意这些细节。比如并集操作,我们在合并两个数组的时候肯定用到过。比如交集操作,我们在查找两个数组中公共元素的时候就会用到。所以其实我们在工作中已经用过或者说经常使用这些类似于集合操作的思想。

  

  最后,由于本人水平有限,能力与大神仍相差甚远,若有错误或不明之处,还望大家不吝赐教指正。非常感谢!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/124423.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 分治法-大整数乘法

    分治法-大整数乘法问题分析:在计算机上处理一些大数据相乘时,由于计算机硬件的限制,不能直接进行相乘得到想要的结果。可以将一个大的整数乘法分而治之,将大问题变成小问题,变成简单的小数乘法再进行合并,从而解决上述问题。当分解到只有一位数时,乘法就很简单了。算法设计:分解:首先将2个大整数a(n位)、b(m位)分解为两部分:ah和al、bh和blah表示大整数a的高位,al表示大整数a的…

  • RC522读卡器 M1卡学习总结(二)

    RC522读卡器 M1卡学习总结(二)二、说说RC522读卡器       我从淘宝里买来的读卡器模块如下:M1卡 学习总结(二)”title=”RC522读卡器 M1卡 学习总结(二)”style=”margin:0px;padding:0px;border:0px;list-style:none”>它带有一组接口:SDA  SCK  MOSI  MISO  IRQ(NG)  GND  RST  3

  • mediumtext_text长度不够用,改为mediumtext感觉 又太大,有没什么方法?

    mediumtext_text长度不够用,改为mediumtext感觉 又太大,有没什么方法?楼主先要搞清楚,text和longtext这些都是可变长度的字段类型.这是phpMyAdmin里的说明:text:最多存储65535(2^16-1)字节的文本字段,存储时在内容前使用2字节表示内容的字节数.longtext:最多存储4294967295字节即4GB(2^32-1)的文本字段,存储时在内容前使用4字节表示内容的字节数.也就是说,你在longtext类型的字段里只存1个字符,占用空…

  • xfire框架内部基本结构解析

    xfire框架内部基本结构解析1概述xfire是webservice的一个实现框架,是apache旗下CXF的前身,是一个比较被广泛使用的webservice框架,网上有很多关于如何使用xfire或cxf的helloworld

  • webpack基础打包命令_逆向webpack打包后的js

    webpack基础打包命令_逆向webpack打包后的js没有配置文件的打包如果我们没有使用配置文件webpack.config.js,那么我们就需要通过命令来打包案例我们首先创建一个webpackTest文件夹,然后在文件夹中再创建2个子文件夹dis

  • 伽马校正-「建议收藏」

    伽马校正-「建议收藏」伽马校正问题描述:读取图像,然后对图像进行伽玛校正。伽马校正这里是一篇写伽马校正比较好的文章,我觉得可以作为背景知识补充。伽马校正用来对照相机等电子设备传感器的非线性光电转换特性进行校正。如果图像原样显示在显示器等上,画面就会显得很暗。伽马校正通过预先增大RGB的值来排除显示器的影响,达到对图像修正的目的。由于下式引起非线性变换,在该式中,xxx被归一化,限定在[0,1][0,1][0,1]范围内。ccc是常数,ggg为伽马变量(通常取2.22.22.2):x′=c Iingx

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号