-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { type SetType } from './type'; | ||
|
||
/** | ||
* 集合数据结构 | ||
* 特性:集合中的数据结构都是无序且唯一 | ||
* | ||
* 该数据结构在ES6中已经存在 | ||
* @link https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set | ||
* 集合方法:交、并、差、子 | ||
*/ | ||
export default class Set<T> implements SetType<T> { | ||
items: Record<any, T>; | ||
|
||
constructor() { | ||
// 使用对象来模拟数据结构的唯一性 | ||
this.items = {}; | ||
} | ||
|
||
delete(e: T) { | ||
if (this.has(e)) { | ||
delete this.items[e]; | ||
return true; | ||
} | ||
return false; | ||
} | ||
has(e: T) { | ||
return Object.prototype.hasOwnProperty.call(this.items, e as any); | ||
} | ||
clear() { | ||
this.items = {}; | ||
} | ||
size() { | ||
return Object.keys(this.items).length; | ||
} | ||
values() { | ||
return Object.values(this.items); | ||
} | ||
|
||
add(e: T) { | ||
if (!this.has(e)) { | ||
this.items[`${e}`] = e; | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
union(o: SetType<T>) { | ||
const res = new Set<T>(); | ||
this.values().forEach((d) => res.add(d)); | ||
o.values().forEach((e) => res.add(e)); | ||
return res; | ||
} | ||
|
||
intersection(o: SetType<T>) { | ||
const res = new Set<T>(); | ||
|
||
this.values().forEach((e) => { | ||
if (o.has(e)) { | ||
res.add(e); | ||
} | ||
}); | ||
|
||
return res; | ||
} | ||
|
||
difference(o: SetType<T>) { | ||
const res = new Set<T>(); | ||
this.values().forEach((e) => { | ||
if (!o.has(e)) { | ||
res.add(e); | ||
} | ||
}); | ||
|
||
return res; | ||
} | ||
|
||
isSubsetOf(o: SetType<T>) { | ||
if (this.size() > o.size()) { | ||
return false; | ||
} | ||
|
||
return this.values().every((e) => o.has(e)); | ||
} | ||
|
||
toString() { | ||
return this.values().join(','); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
export interface SetType<T> { | ||
/** | ||
* 添加一个元素到集合中 | ||
* @param e | ||
* @returns | ||
*/ | ||
add: (e: T) => boolean; | ||
|
||
delete: (e: T) => boolean; | ||
|
||
/** | ||
* 是否包含该元素 | ||
* @param e | ||
* @returns | ||
*/ | ||
has: (e: T) => boolean; | ||
|
||
/** | ||
* 清空集合 | ||
* @returns | ||
*/ | ||
clear: () => void; | ||
|
||
/** | ||
* 返回集合长度 | ||
* @returns | ||
*/ | ||
size: () => number; | ||
|
||
/** | ||
* 返回一个饱含集合元素的所有值的数组 | ||
* @returns | ||
*/ | ||
values: () => Array<T>; | ||
|
||
/** | ||
* 求两个集合的并集 | ||
* @returns | ||
*/ | ||
union: (o: SetType<T>) => SetType<T>; | ||
|
||
/** | ||
* 求两个集合的交集 | ||
* @param o | ||
* @returns | ||
*/ | ||
intersection: (o: SetType<T>) => SetType<T>; | ||
|
||
/** | ||
* 差集 | ||
* @param o | ||
* @returns | ||
*/ | ||
difference: (o: SetType<T>) => SetType<T>; | ||
|
||
/** | ||
* 是否为子集 | ||
* @param o | ||
* @returns | ||
*/ | ||
isSubsetOf: (o: SetType<T>) => boolean; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import Set from '../book/set'; | ||
|
||
describe('test set ', () => { | ||
it('test set init', () => { | ||
const set = new Set(); | ||
|
||
expect(set.size()).toBe(0); | ||
}); | ||
|
||
it('test union', () => { | ||
const first = new Set<number>(); | ||
first.add(1); | ||
first.add(4); | ||
first.add(5); | ||
|
||
const second = new Set<number>(); | ||
second.add(4); | ||
second.add(3); | ||
second.add(1); | ||
|
||
expect(first.union(second).toString()).toBe('1,3,4,5'); | ||
}); | ||
|
||
it('test intersection', () => { | ||
const first = new Set<number>(); | ||
first.add(1); | ||
first.add(4); | ||
first.add(5); | ||
|
||
const second = new Set<number>(); | ||
second.add(4); | ||
second.add(3); | ||
second.add(1); | ||
|
||
expect(first.intersection(second).toString()).toBe('1,4'); | ||
}); | ||
|
||
it('test difference', () => { | ||
const first = new Set<number>(); | ||
first.add(1); | ||
first.add(4); | ||
first.add(5); | ||
|
||
const second = new Set<number>(); | ||
second.add(4); | ||
second.add(3); | ||
second.add(1); | ||
|
||
expect(first.difference(second).toString()).toBe('5'); | ||
}); | ||
|
||
it('test isSubsetOf', () => { | ||
const first = new Set<number>(); | ||
first.add(1); | ||
first.add(4); | ||
first.add(5); | ||
|
||
const second = new Set<number>(); | ||
second.add(4); | ||
second.add(3); | ||
second.add(1); | ||
|
||
expect(first.isSubsetOf(second)).toBe(false); | ||
}); | ||
}); |