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数据结构与算法(第十一章)—— 算法模式
本章将会学习递归.动态规划和贪心算法. 第十一章 算法模式 递归 递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题.递归通常涉及函数调用自身. 递归函数是像下面能够直接调用自身的 ...
随机推荐
- (转)SQLite内置函数
一.聚合函数: SQLite中支持的聚合函数在很多其他的关系型数据库中也同样支持,因此我们这里将只是给出每个聚集函数的简要说明,而不在给出更多的示例了.这里还需要进一步说明的是,对于所有聚合函数而言, ...
- Eclipse项目中web app libraries和 Referenced Libraries区别
Referenced Libraries是编译环境下使用的JAR包,所谓编译环境下使用的JAR包, 就是说你在Eclipse中进行源文件的编写的时候,所需要引用到的类都从Referenced Li ...
- ECEF和大地坐标系的相互转化
在阅读 RTKLIB的源码时,发现了ECEF和大地坐标系的相互转换的函数,大地坐标系(φ,λ,h)转成ECEF(X,Y,Z)与所看书籍(GPS原理与接收机,谢刚,电子工业出版社)的公式是一样的,而EC ...
- (译文)React----React应用程序流式服务端渲染
好处 React16推出了流式服务端渲染,它允许你并行地分发HTML片段.这样可以让渲染 出的首字节有意义的内容给用户速度更快. (例子1,上面部分是一次性转换,下面是流渲染,两种方式) 而且相对re ...
- TCP和UDP的最完整的区别
TCP UDP TCP与UDP基本区别 1.基于连接与无连接 2.TCP要求系统资源较多,UDP较少: 3.UDP程序结构较简单 4.流模式(TCP)与数据报模式(UDP); ...
- Session的过期时间如何计算?
在生成session的时候,会设置一个session过期时间.session的过期时间并不是从生成session对象开始计算,超过过期时间,session就失效了. 而是每当一个浏览器请求,sessi ...
- centos 安装配置 mysql
安装环境:CentOS7 64位 MINI版,安装MySQL5.7 1.配置YUM源 在MySQL官网中下载YUM源rpm安装包:http://dev.mysql.com/downloads/repo ...
- Linux "零拷贝" sendfile函数中文说明及实际操作
Sendfile函数说明 #include ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); sendfile ...
- MVC Form 表单 提交 集合 及 复杂对象
public class Customer { public string FName{get;set;} public Address address{get;set;} } public clas ...
- Linux进程管理:查杀进程
一.查看进程 Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux.这两个到底有什么区别呢? 两者没太大差别,讨论这个问题,要追溯到Unix系统中的两种风格,System V风格 ...