JavaScript数据结构与算法(八) 集合(ECMAScript 6中定义的类似的Set类)
// 特性:
// 1. 集合是由一组无序且唯一(即不能重复)的项组成的。这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中。
// 2. 也可以把集合想象成一个既没有重复元素,也没有顺序概念的数组
// 3. 在数学中,集合也有并集、交集、差集等基本操作。在这一章中我们也会介绍这些操作 // 集合操作
// 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合
// 并集的数学概念,集合A和B的并集,表示为A∪B,定义如下:
// A∪B = { x | x ∈ A∨x ∈ B }
// 意思是x(元素)存在于A中,或x存在于B中。下图展示了并集操作:
// 并集.png // 交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合
// 交集的数学概念,集合A和B的交集,表示为A∩B,定义如下:
// A∩B = { x | x ∈ A∧x ∈ B }
// 意思是x(元素)存在于A中,且x存在于B中。下图展示了交集操作:
// 交集.png // 差集:对于给定的两个集合,返回一个包含所有存在与第一个集合且不存在与第二个集合的元素的新集合
// 差集的数学概念,集合A和B的差集,表示为AB,定义如下:
// AB = { x | x ∈ A ∧ x B }
// 意思是x(元素)存在于A中,且x不存在于B中。下图展示了集合A和B的差集操作:
// 差集.png // 子集:验证一个给定集合是否是另一个集合的子集
// 最后一个集合操作是子集。子集的数学概念,集合A是B的子集(或集合B包含
// 了A) ,表示为A⊆B,定义如下:
// ∀x { x ∈ A → x ∈ B }
// 意思是集合A中的每一个x(元素) ,也需要存在于B中。下图展示了集合A是集合B的子集:
// 子集.png
class Set {
private items: Object = {};
/**
* 向集合添加一个新的项
* @param value
*/
public add(value) {
if (!this.has(value)) {
this.items[value] = value;
return true;
}
}
/**
* 从集合移除一个值
* @param value
*/
public remove(value) {
if (this.has(value)) {
delete this.items[value];
return true;
}
return false;
}
/**
* 如果值在集合中,返回true,否则返回false
* @param value
*/
public has(value) {
return this.items.hasOwnProperty(value);
}
/**
* 移除集合中的所有项
*/
public clear() {
this.items = {};
}
/**
* 返回集合所包含元素的数量。与数组的length属性类似
*/
public size() {
var count = ;
for (var prop in this.items) { //{5}
if (this.items.hasOwnProperty(prop)) //{6}
++count; //{7}
}
return count;
}
/**
* 返回一个包含集合中所有值的数组
*/
public values() {
var keys = [];
for (var key in this.items) { //{7}
keys.push(key); //{8}
}
return keys;
}
public union(otherSet: Set): Set {
let unionSet = new Set();
let values = this.values();
for (let i = ; i < values.length; i++) {
unionSet.add(values[i]);
}
values = otherSet.values();
for (let i = ; i < values.length; i++) {
unionSet.add(values[i]);
}
return unionSet;
}
public intersection(otherSet: Set) {
let intersectionSet = new Set();
let values = this.values();
for (let i = ; i < values.length; i++) {
if (otherSet.has(values[i])) {
intersectionSet.add(values[i]);
}
}
return intersectionSet;
}
public difference(otherSet: Set) {
let differenceSet = new Set();
let values = this.values();
for (let i = ; i < values.length; i++) {
if (!otherSet.has(values[i])) {
differenceSet.add(values[i]);
}
}
return differenceSet;
}
public subset(otherSet: Set) {
if (this.size() > otherSet.size()) {
return false;
} else {
let values = this.values();
for (let i = ; i < values.length; i++) {
if (!otherSet.has(values[i])) {
return false;
}
}
return true;
}
}
}
// 使用 Set 类
let set = new Set(); set.add();
console.log(set.values()); //输出["1"]
console.log(set.has()); //输出true
console.log(set.size()); //输出1 set.add();
console.log(set.values()); //输出["1", "2"]
console.log(set.has()); //true
console.log(set.size()); //2 set.remove();
console.log(set.values()); //输出["2"] set.remove();
console.log(set.values()); //输出[] // 测试一下并集的代码:
var setA = new Set();
setA.add();
setA.add();
setA.add(); var setB = new Set();
setB.add();
setB.add();
setB.add();
setB.add(); var unionAB = setA.union(setB);
console.log(unionAB.values()); // 测试一下交集的代码
var setA = new Set();
setA.add();
setA.add();
setA.add(); var setB = new Set();
setB.add();
setB.add();
setB.add(); var intersectionAB = setA.intersection(setB);
console.log(intersectionAB.values());
//输出为["2", "3"],因为2和3同时存在于两个集合中 // 测试一下差集的代码
var setA = new Set();
setA.add();
setA.add();
setA.add(); var setB = new Set();
setB.add();
setB.add();
setB.add(); var differenceAB = setA.difference(setB);
console.log(differenceAB.values());
//输出为["1"],因为1是唯一一个仅存在于setA的元素。 // 测试一下子集的代码
var setA = new Set();
setA.add();
setA.add(); var setB = new Set();
setB.add();
setB.add();
setB.add(); var setC = new Set();
setC.add();
setC.add();
setC.add(); console.log(setA.subset(setB));
console.log(setA.subset(setC));
// 我们有三个集合:setA是setB的子集 (因此输出为true) , 然而setA不是setC的子集 (setC
// 只包含了setA中的2,而不包含1) ,因此输出为false
使用 Set 类
总结:我们将从头实现一个与ECMAScript 6中定义的类似的Set类。我们还介绍了在其他编程语言的集合数据结构的实现中不常见的一些方法,比如并集、交集、差集和子集。因此,相比于其他编程语言目前的Set实现,我们实现了一个非常完备的Set类
var Set = (function () {
function Set() {
this.items = {};
}
/**
* 向集合添加一个新的项
* @param value
*/
Set.prototype.add = function (value) {
if (!this.has(value)) {
this.items[value] = value;
return true;
}
};
/**
* 从集合移除一个值
* @param value
*/
Set.prototype.remove = function (value) {
if (this.has(value)) {
delete this.items[value];
return true;
}
return false;
};
/**
* 如果值在集合中,返回true,否则返回false
* @param value
*/
Set.prototype.has = function (value) {
return this.items.hasOwnProperty(value);
};
/**
* 移除集合中的所有项
*/
Set.prototype.clear = function () {
this.items = {};
};
/**
* 返回集合所包含元素的数量。与数组的length属性类似
*/
Set.prototype.size = function () {
var count = ;
for (var prop in this.items) {
if (this.items.hasOwnProperty(prop))
++count; //{7}
}
return count;
};
/**
* 返回一个包含集合中所有值的数组
*/
Set.prototype.values = function () {
var keys = [];
for (var key in this.items) {
keys.push(key); //{8}
}
return keys;
};
Set.prototype.union = function (otherSet) {
var unionSet = new Set();
var values = this.values();
for (var i_1 = ; i_1 < values.length; i_1++) {
unionSet.add(values[i_1]);
}
values = otherSet.values();
for (var i_2 = ; i_2 < values.length; i_2++) {
unionSet.add(values[i_2]);
}
return unionSet;
};
Set.prototype.intersection = function (otherSet) {
var intersectionSet = new Set();
var values = this.values();
for (var i_3 = ; i_3 < values.length; i_3++) {
if (otherSet.has(values[i_3])) {
intersectionSet.add(values[i_3]);
}
}
return intersectionSet;
};
Set.prototype.difference = function (otherSet) {
var differenceSet = new Set();
var values = this.values();
for (var i_4 = ; i_4 < values.length; i_4++) {
if (!otherSet.has(values[i_4])) {
differenceSet.add(values[i_4]);
}
}
return differenceSet;
};
Set.prototype.subset = function (otherSet) {
if (this.size() > otherSet.size()) {
return false;
}
else {
var values = this.values();
for (var i_5 = ; i_5 < values.length; i_5++) {
if (!otherSet.has(values[i_5])) {
return false;
}
}
return true;
}
};
return Set;
}());
JavaScript数据结构与算法(八) 集合(ECMAScript 6中定义的类似的Set类)的更多相关文章
- JavaScript 数据结构与算法之美 - 非线性表中的树、堆是干嘛用的 ?其数据结构是怎样的 ?
1. 前言 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手. 非线性表(树.堆),可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法 ...
- javascript数据结构与算法-- 二叉树
javascript数据结构与算法-- 二叉树 树是计算机科学中经常用到的一种数据结构.树是一种非线性的数据结构,以分成的方式存储数据,树被用来存储具有层级关系的数据,比如文件系统的文件,树还被用来存 ...
- 为什么我要放弃javaScript数据结构与算法(第六章)—— 集合
前面已经学习了数组(列表).栈.队列和链表等顺序数据结构.这一章,我们要学习集合,这是一种不允许值重复的顺序数据结构. 本章可以学习到,如何添加和移除值,如何搜索值是否存在,也可以学习如何进行并集.交 ...
- JavaScript数据结构与算法-集合练习
集合的实现 function Set () { this.dataStore = []; this.add = add; this.remove = remove; this.size = size; ...
- 重读《学习JavaScript数据结构与算法-第三版》-第2章 ECMAScript与TypeScript概述
定场诗 八月中秋白露,路上行人凄凉: 小桥流水桂花香,日夜千思万想. 心中不得宁静,清早览罢文章, 十年寒苦在书房,方显才高志广. 前言 洛伊安妮·格罗纳女士所著的<学习JavaScript数据 ...
- 为什么我要放弃javaScript数据结构与算法(第一章)—— JavaScript简介
数据结构与算法一直是我算比较薄弱的地方,希望通过阅读<javaScript数据结构与算法>可以有所改变,我相信接下来的记录不单单对于我自己有帮助,也可以帮助到一些这方面的小白,接下来让我们 ...
- 重读《学习JavaScript数据结构与算法-第三版》- 第4章 栈
定场诗 金山竹影几千秋,云索高飞水自流: 万里长江飘玉带,一轮银月滚金球. 远自湖北三千里,近到江南十六州: 美景一时观不透,天缘有分画中游. 前言 本章是重读<学习JavaScript数据结构 ...
- JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)
前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...
- 为什么我要放弃javaScript数据结构与算法(第十一章)—— 算法模式
本章将会学习递归.动态规划和贪心算法. 第十一章 算法模式 递归 递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题.递归通常涉及函数调用自身. 递归函数是像下面能够直接调用自身的 ...
随机推荐
- Java中如何创建线程
Java中如何创建线程 两种方式:1)继承Thread类:2)实现Runnable接口. 1.继承Thread类 继承Thread类,重写run方法,在run方法中定义需要执行的任务. class M ...
- Android一个小巧的记录app(便签或者日记 随心)
入驻博客园两个月今天第一次发随笔,,话不多说,直接上图展示效果 主界面用的RecyclerView的瀑布流(StaggeredGridLayoutManager),同时加上Floatbutton悬浮按 ...
- 使用cocopod管理第三方
扭捏了两年多一直不愿意使用cocopod来管理第三方,一直感觉直接拖拽第三方就挺方便的,直到今天使用第三方库WebViewJavascriptBridge,拖拽一直有问题,不得已研究.使用了cocop ...
- Java基础学习笔记二十六 JDBC
什么是JDBC JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库,J ...
- 【java并发系列】Fork/Join任务(转)
原文链接 当我们需要执行大量的小任务时,有经验的Java开发人员都会采用线程池来高效执行这些小任务.然而,有一种任务,例如,对超过1000万个元素的数组进行排序,这种任务本身可以并发执行,但如何拆解成 ...
- Beta总结篇
45°炸 031502601 蔡鸿杰 031502604 陈甘霖 031502632 伍晨薇 一.项目预期进展及现实进展 项目预期计划 现实进展 Github使用 √ 日拍 (调用相机.相册) √ 足 ...
- SpringMVC 无法访问到指定jsp页面可能的原因
当出现你的程序可以访问到对应的controller层.但是却无法访问对应的jsp文件时.你首先做的不是检查web.xml等配置文件,而是打开的服务器根文件检查对应路径下的文件是否存在.命名是否正确.命 ...
- 【微软大法好】VS Tools for AI全攻略
大家都知道微软在Connect();17大会上发布了VS Tools for AI,旨在提升Visual Studio和VSCode对日益增长的深度学习需求的体验.看了一圈,网上似乎没有一个完整的中文 ...
- CentOS7下安装python-pip
一.检查是否已经安装 检查linux有没有安装python-pip包,直接执行:: yum install python-pip 二.安装 pip install 1.没有python-pip包就执行 ...
- SpringCloud的Config:ConfigServer注册到EurekaServer中,变成一个Eureka服务
一.概念与定义 1.将SpringCloud ConfigServer注册到 EurekaServer,以便ConfigClient以服务的方式引用ConfigServer 2.客户端不再引用 Con ...