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数据结构与算法(第十一章)—— 算法模式
本章将会学习递归.动态规划和贪心算法. 第十一章 算法模式 递归 递归是一种解决问题的方法,它解决问题的各个小部分,直到解决最初的大问题.递归通常涉及函数调用自身. 递归函数是像下面能够直接调用自身的 ...
随机推荐
- 如何在C#项目中使用NHibernate
现代化大型项目通常使用独立的数据库来存储数据,其中以采用关系型数据库居多.用于开发项目的高级语言(C#.Java等)是面向对象的,而关系型数据库是基于关系的,两者之间的沟通需要一种转换,也就是对象/关 ...
- lua 二维数组创建
local arr= {} for i=1, 4 do arr[i] = {} end 使用时可以直接使用arr[i][j]
- SSH相关知识
SSH(Secure Shell, 安全Shell协议)是一种加密的网络传输协议,经常用于安全的远程登录. SSH只是一种协议,可以有多种实现. OPENSSH是一种应用广泛的实现. sshd是dae ...
- Java基础学习笔记三 Java基础语法
Scanner类 Scanner类属于引用数据类型,先了解下引用数据类型. 引用数据类型的使用 与定义基本数据类型变量不同,引用数据类型的变量定义及赋值有一个相对固定的步骤或格式. 数据类型 变量名 ...
- 2018.3.29 DIV位置调整代码
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- C语言函数嵌套调用作业
一.实验作业 1.1 PTA题目:6-4 十进制转换二进制 设计思路 如果n大于1 对n/2继续进行该函数运算 输出n%2的值 代码截图 调试问题 我第一次做的时候判断的边界条件是大于0继续进行运算, ...
- C语言第四次作业--嵌套循环
一.PTA实验作业 题目1:打印九九口诀表 1.本题PTA提交列表 2.设计思路 (1)定义三个整形变量n,j,i,n表示任意给定的正整数. (2)输入一个正整数n. (3)令i=1,i<=n, ...
- 冲刺NO.2
Alpha冲刺第二天 站立式会议 项目进展 团队成员在确定了所需技术之后,开始学习相关技术的使用,其中包括了HTML5,CSS与SSH框架等开发技术.并且在项目分工配合加以总结和完善,对现有发现的关于 ...
- SQL数据库开发中的一些经典代码
1.按姓氏笔画排序: Select * From TableName Order By CustomerName Collate Chinese_PRC_Stroke_ci_as 2.数据库加密: ...
- java方法的定义格式
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,声明格式为: [修饰符1 修饰符2 …..] 返回值类型 方法名( 形式参数列表 ){ Java 语句;… … … } 例如 ...