Skip to content

Commit

Permalink
feat: complete chap7 set code
Browse files Browse the repository at this point in the history
  • Loading branch information
javaswing committed Nov 22, 2023
1 parent 05f998f commit c25003f
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 0 deletions.
89 changes: 89 additions & 0 deletions code/set/book/set.ts
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(',');
}
}
62 changes: 62 additions & 0 deletions code/set/book/type.ts
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;
}
65 changes: 65 additions & 0 deletions code/set/test/set.test.ts
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);
});
});

0 comments on commit c25003f

Please sign in to comment.