类层次与抽象类
抽象与具体的集合类层次(Sets.js)
/* AbstractSet 是具有 has 方法的集合 */
class AbstractSet {
has(x) {
throw new Error(`Abstract method`);
}
}
/* 集合中不属于给定集合的所有元素的集合 */
class NotSet extends AbstractSet {
constructor(set) {
super();
this.set = set;
}
has(x) {
return !this.set.has(x);
}
toString() {
return `{x|x∉${this.set.toString()}}`;
}
}
/* RangeSet 是一组从下限到上限的整数 */
class RangeSet extends AbstractSet {
constructor(from, to) {
super();
this.from = from;
this.to = to;
}
has(x) {
return x >= this.from && x <= this.to;
}
toString() {
return `{x|${this.from}<=x<=${this.to}}`;
}
}
/* AbstractEnumerableSet 是一个有大小并且可以迭代的集合 */
class AbstractEnumerableSet extends AbstractSet {
get size() {
throw new Error("AbsTract method");
}
[Symbol.iterator]() {
throw new Error("Abstract method");
}
isEmpty() {
return this.size === 0;
}
toString() {
return `{${Array.from(this).join(',')}}`;
}
equals(set) {
if (!(set instanceof AbstractEnumerableSet)) {
return false;
}
if (this.size !== set.size) return false;
for (let element of this) {
if (!set.has(element)) return false;
}
return true;
}
}
/* 单例集是包含单个元素的集合 */
class SingletonSet extends AbstractEnumerableSet {
constructor(member) {
super();
this.member = member;
}
has(x) {
return x === this.member;
}
get size() {
return 1;
}
*[Symbol.iterator]() {
yield this.member;
}
}
/* 可以修改的集合 */
class AbstractWritableSet extends AbstractEnumerableSet {
insert(x) {
throw new Error("Abstract method");
}
remove(x) {
throw new Error("Abstract method");
}
add(set) {
for (let element of set) {
this.insert(element);
}
}
subtract(set) {
for (let element of set) {
this.remove(element);
}
}
intersect(set) {
for (let element of this) {
if (!set.has(element)) {
this.remove(element);
}
}
}
}
/* BitSet 是一组整数 */
class BitSet extends AbstractWritableSet {
constructor(max) {
super();
this.max = max;
this.n = 0;
this.numBytes = Math.floor(max / 8) + 1;
this.data = new Uint8Array(this.numBytes);
}
_valid(x) {
return Number.isInteger(x) && x >= 0 && x <= this.max;
}
_has(byte, bit) {
return (this.data[byte] & BitSet.bits[bit]) !== 0;
}
has(x) {
if (this._valid(x)) {
let byte = Math.floor(x / 8);
let bit = x % 8;
return this._has(byte, bit);
} else {
return false;
}
}
insert(x) {
if (this._valid(x)) {
let byte = Math.floor(x / 8);
let bit = x % 8;
if (!this._has(byte, bit)) {
this.data[byte] |= BitSet.bits[bit];
this.n++;
}
} else {
throw new TypeError("Invalid set element:" + x);
}
}
remove(x) {
if (this._valid(x)) {
let byte = Math.floor(x / 8);
let bit = x % 8;
if (this._has(byte, bit)) {
this.data[byte] &= ~BitSet.masks[bit];
this.n--;
}
} else {
throw new TypeError("Invalid set element:" + x);
}
}
get size() {
return this.n;
}
*[Symbol.iterator]() {
for (let i = 0; i <= this.max; i++) {
if (this.has(i)) {
yield i;
}
}
}
}
/* 初始化 `BitSet.bits`,其中 `BitSet.bits[i]` 是 `i` 的二进制表示中最低位的 1 的位置。 */
BitSet.bits = new Uint8Array([1, 2, 4, 8, 16, 32, 64, 128]);
/* 初始化 `BitSet.masks`,其中 `BitSet.masks[i]` 是 `i` 的二进制表示中最低位的 1 的位置。 */
BitSet.masks = new Uint8Array([~1, ~2, ~4, ~8, ~16, ~32, ~64, ~128]);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现