用js来实现那些数据结构10(集合02-集合的操作)
前一篇文章我们一起实现了自定义的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原生的接口罢了。大家可以尝试着对比一下这两种类型的代码。加深印象。
到这里集合就介绍完毕了。回顾一下代码,我们发现其实集合的各种操作方法在我们的实际工作中也是经常应用到的,只是我们在用数组操作,并没有十分的去注意这些细节。比如并集操作,我们在合并两个数组的时候肯定用到过。比如交集操作,我们在查找两个数组中公共元素的时候就会用到。所以其实我们在工作中已经用过或者说经常使用这些类似于集合操作的思想。
最后,由于本人水平有限,能力与大神仍相差甚远,若有错误或不明之处,还望大家不吝赐教指正。非常感谢!
用js来实现那些数据结构10(集合02-集合的操作)的更多相关文章
- 用js来实现那些数据结构—目录
首先,有一点要声明,下面所有文章的所有内容的代码,都不是我一个人独立完成的,它们来自于一本叫做<学习JavaScript数据结构和算法>(第二版),人民邮电出版社出版的这本书.github ...
- 用js来实现那些数据结构及算法—目录
首先,有一点要声明,下面所有文章的所有内容的代码,都不是我一个人独立完成的,它们来自于一本叫做<学习JavaScript数据结构和算法>(第二版),人民邮电出版社出版的这本书.github ...
- 用js来实现那些数据结构09(集合01-集合的实现)
说到集合,第一个想到的就是中学学到的那个数学概念:集合.在我们开始集合相关的js实现前,我们有必要来了解一下什么是集合以及集合的数学概念. 好吧,我们一起来复习一下早就被我们遗忘的集合. 集合是由一组 ...
- 第10讲-Java集合框架
第10讲 Java集合框架 1.知识点 1.1.课程回顾 1.2.本章重点 1.2.1 List 1.2.2 Set 1.2.3 Map 2.具体内容 2.1.Java集合框架 2.1.1 为什么需要 ...
- js前台取用后台传递过来的map集合方式
在处理有些特殊需求的时候,我们需要在前台页面的js中获取后台传递过来的map集合类型的参数,并且进行调用,代码如下: 在后台我们拼装出如下的集合: Map<String,Grade> gr ...
- (js描述的)数据结构 [数组的一些补充](1)
(js描述的)数据结构 [数组的一些补充](1) 1. js的数组: 1.优点:高度封装,对于数组的操作就是调用API 2.普通语言的数组: 1.优点:根据index来查询,修改数据效率很高 2.缺点 ...
- D3.js的基础部分之数组的处理 集合(Set)(v3版本)
数组的处理 之 集合(set) 集合(Set)是数学中常用的概念,表示具有某种特定性质的事物的总体.集合里的项叫做元素.集合的相关方法有: d3.set([array]) //使用数组来构建集合, ...
- [集合]Collection集合框架源码分析
Collection接口 在java的集合类库中,基本接口是Collection,该接口的在集合中的源码定义如下(将源码中的注释删掉了): public interface Collection< ...
- Java 集合学习--集合概述
一.集合框架 集合,通常也叫容器,java中有多种方式保存对象,集合是java保存对象(对象的引用)的方式之一,之前学习的数组是保存对象的最有效的方式,但是数组却存在一个缺陷,数组的大小是固定的,但是 ...
随机推荐
- Mysql加密解密随机函数
MD5(str) md5加密 SELECT MD5('hello') 5d41402abc4b2a76b9719d911017c592 sha(str) sha加密 SELECT SHA('hello ...
- iPhone的App嵌入html页面问题
测试环境:iPhone ios 11.0.3 问题:iPhone App嵌入HTML页面,页面拉动到底部时,手势从屏幕底部边缘开始往上拉动,页面出现白色图层,且html页面一屏外的会卡住,无法滚动,需 ...
- 利用jmeter做一个简单的性能测试并进行参数化设置
1.新增一个线程组,并在下面添加基本原件,包括:监听器.http请求默认值和一个事务控制器 在http请求默认值中填写 ip 地址和端口号,协议类型默认为http 2.添加代理服务器,以便之后进行录制 ...
- 项目Alpha冲刺Day1
一.会议照片 二.项目进展 1.今日安排 讨论完成项目的详细设计,并完成数据库的设计,学习powerDesigner的使用 2.问题困难 powerDesigner导出sql语句因为问题无法导入,特别 ...
- 201621123057 《Java程序设计》第10周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出现什 ...
- 安装QT5.02
1.下载QT5 SDK 下载地址:http://qt-project.org/downloads. 2.安装QT5 下载完后,假设放在Download/,切换到该目录,输入:./qt-linux-op ...
- Java基础 成员变量的继承与覆盖
通过继承可以得到父类的成员变量,子类的成员变量包括从父类继承的成员变量(包括从祖先类中继承的成员变量)以及子类中重新定义的成员变量.本次介绍内容包括:可以继承哪些成员?如果子类和父类出现了相同的成员变 ...
- python的项目结构
项目结构 知识点 创建项目,编写 __init__ 文件 使用 setuptools 模块,编写 setup.py 和 MANIFEST.in 文件 创建源文件的发布版本 项目注册&上传到 P ...
- caffe实现GAN
我实现GAN网络结构比较复杂: 通过建立两个一模一样的网络,他们相对应的层共享权重,一个网络用来跟新D model另一个网络用来更新G model 更新G model的网络,D部分只进行梯度传递,不进 ...
- js中严格模式
我们在js中可以使用"use strict";定义了我们在接下来的文档输写中 将按照严格模式进行: function(){ "use strict'; ;// 在这里我们 ...