From eb93939f689d7323a4ee30c49d7ef48f298acc0c Mon Sep 17 00:00:00 2001 From: danielsss Date: Tue, 20 Dec 2022 12:02:21 +1100 Subject: [PATCH] added: typescript hash func --- .../chapter_hashing/array_hash_map.ts | 137 ++++++++++++++++++ codes/typescript/chapter_hashing/hash_map.ts | 45 ++++++ codes/typescript/tsconfig.json | 16 ++ docs/chapter_hashing/hash_map.md | 110 +++++++++++++- hello-algo.iml | 11 ++ 5 files changed, 317 insertions(+), 2 deletions(-) create mode 100644 codes/typescript/chapter_hashing/array_hash_map.ts create mode 100644 codes/typescript/chapter_hashing/hash_map.ts create mode 100644 codes/typescript/tsconfig.json create mode 100644 hello-algo.iml diff --git a/codes/typescript/chapter_hashing/array_hash_map.ts b/codes/typescript/chapter_hashing/array_hash_map.ts new file mode 100644 index 000000000..d56fb8fd7 --- /dev/null +++ b/codes/typescript/chapter_hashing/array_hash_map.ts @@ -0,0 +1,137 @@ +/* 键值对 int->String */ +class Entry { + public key: number; + public val: string; + constructor(key: number, val: string) { + this.key = key; + this.val = val; + } +} + +/* 数组的初始化和基本操作 */ +class ArrayList { + + private readonly elements: Entry[]; + constructor(length: number) { + this.elements = new Array(length); + this.initialize(); + } + + /* 初始化 */ + private initialize() { + this.elements.fill(null as any, 0, this.elements.length - 1); + } + + /* 新增和删除 */ + public set(key: number, val: string | null) { + this.isOutOfRange(key); + if (val !== null) { + this.elements[key] = new Entry(key, val); + } + this.elements[key] = null as any; + } + + /* 获取 */ + public get(key: number): string { + return this.elements[key].val; + } + + public entrySet() { + let arr = []; + for (let i = 0; i < this.elements.length; i++) { + if (this.elements[i] !== null) { + arr.push(this.elements[i]); + } + } + return arr; + } + + public valueSet() { + let arr = []; + for (let i = 0; i < this.elements.length; i++) { + if (this.elements[i] !== null) { + arr.push(this.elements[i].val); + } + } + return arr; + } + + public keySet() { + let arr = []; + for (let i = 0; i < this.elements.length; i++) { + if (this.elements[i] !== null) { + arr.push(this.elements[i].key); + } + } + return arr; + } + + private isOutOfRange(key: number) { + if (key > this.elements.length - 1) { + throw new Error('Out of array range'); + } + } +} + +/* 基于数组简易实现的哈希表 */ +class ArrayHashMap { + // 初始化一个长度为 100 的桶(数组) + private bucket: ArrayList; + + constructor() { + this.bucket = new ArrayList(100); + } + + /* 哈希函数 */ + private hashFunc(key: number): number { + return key % 100; + } + + /* 查询操作 */ + public get(key: number): string | null { + let index = this.hashFunc(key); + let val = this.bucket.get(index); + if (val === null) { + return null; + } + return val; + } + + /* 添加操作 */ + public put(key: number, val: string) { + let index = this.hashFunc(key); + this.bucket.set(index, val); + } + + /* 删除操作 */ + public remove(key: number) { + let index = this.hashFunc(key); + // 置为 null ,代表删除 + this.bucket.set(index, null); + } + + /* 获取所有键值对 */ + public entrySet(): Entry[] { + return this.bucket.entrySet(); + } + + /* 获取所有键 */ + public keySet(): number[] { + return this.bucket.keySet(); + } + + /* 获取所有值 */ + public valueSet(): string[] { + return this.bucket.valueSet(); + } + +/* 打印哈希表 */ + public print() { + let entrySet = this.entrySet(); + for (const entry of entrySet) { + console.info(`${entry.key} -> ${entry.val}`); + } + } +} + +export default ArrayHashMap; diff --git a/codes/typescript/chapter_hashing/hash_map.ts b/codes/typescript/chapter_hashing/hash_map.ts new file mode 100644 index 000000000..8849d98f3 --- /dev/null +++ b/codes/typescript/chapter_hashing/hash_map.ts @@ -0,0 +1,45 @@ +import ArrayHashMap from './array_hash_map'; + +class HashMap { + + constructor() { + /* 初始化哈希表 */ + const map = new ArrayHashMap(); + /* 添加操作 */ + // 在哈希表中添加键值对 (key, value) + map.put(12836, '小哈'); + map.put(15937, '小啰'); + map.put(16750, '小算'); + map.put(13276, '小法'); + map.put(10583, '小鸭'); + console.info('\n添加完成后,哈希表为\nKey -> Value'); + map.print(); + + /* 查询操作 */ + // 向哈希表输入键 key ,得到值 value + let name = map.get(15937); + console.info('\n输入学号 15937 ,查询到姓名 ' + name); + + /* 删除操作 */ + // 在哈希表中删除键值对 (key, value) + map.remove(10583); + console.info('\n删除 10583 后,哈希表为\nKey -> Value'); + map.print(); + + /* 遍历哈希表 */ + console.info('\n遍历键值对 Key->Value'); + for (const entry of map.entrySet()) { + console.info(entry.key + ' -> ' + entry.val); + } + console.info('\n单独遍历键 Key'); + for (const key of map.keySet()) { + console.info(key); + } + console.info('\n单独遍历值 Value'); + for (const val of map.valueSet()) { + console.info(val); + } + } +} + +export default HashMap; \ No newline at end of file diff --git a/codes/typescript/tsconfig.json b/codes/typescript/tsconfig.json new file mode 100644 index 000000000..c53bf4f72 --- /dev/null +++ b/codes/typescript/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es6", + "moduleResolution": "node", + "resolveJsonModule": true, + "module": "esnext", + "strict": true, + "importHelpers": true, + "noEmit": false, + "sourceMap": true, + "baseUrl": ".", + "esModuleInterop": true, + "downlevelIteration": true, + }, + "include": ["./**/*"], +} diff --git a/docs/chapter_hashing/hash_map.md b/docs/chapter_hashing/hash_map.md index 3a53f5dba..091e1242f 100644 --- a/docs/chapter_hashing/hash_map.md +++ b/docs/chapter_hashing/hash_map.md @@ -138,7 +138,28 @@ comments: true === "TypeScript" ```typescript title="hash_map.ts" + /* 初始化哈希表 */ + const map = new ArrayHashMap(); + /* 添加操作 */ + // 在哈希表中添加键值对 (key, value) + map.put(12836, '小哈'); + map.put(15937, '小啰'); + map.put(16750, '小算'); + map.put(13276, '小法'); + map.put(10583, '小鸭'); + console.info('\n添加完成后,哈希表为\nKey -> Value'); + map.print(); + + /* 查询操作 */ + // 向哈希表输入键 key ,得到值 value + let name = map.get(15937); + console.info('\n输入学号 15937 ,查询到姓名 ' + name); + /* 删除操作 */ + // 在哈希表中删除键值对 (key, value) + map.remove(10583); + console.info('\n删除 10583 后,哈希表为\nKey -> Value'); + map.print(); ``` === "C" @@ -233,7 +254,19 @@ comments: true === "TypeScript" ```typescript title="hash_map.ts" - + /* 遍历哈希表 */ + console.info('\n遍历键值对 Key->Value'); + for (const entry of map.entrySet()) { + console.info(entry.key + ' -> ' + entry.val); + } + console.info('\n单独遍历键 Key'); + for (const key of map.keySet()) { + console.info(key); + } + console.info('\n单独遍历值 Value'); + for (const val of map.valueSet()) { + console.info(val); + } ``` === "C" @@ -477,7 +510,80 @@ $$ === "TypeScript" ```typescript title="array_hash_map.ts" - + /* 键值对 int->String */ + class Entry { + public key: number; + public val: string; + constructor(key: number, val: string) { + this.key = key; + this.val = val; + } + } + + /* 数组的初始化和基本操作 */ + class ArrayList { + + private readonly elements: Entry[]; + constructor(length: number) { + this.elements = new Array(length); + this.initialize(); + } + + /* 初始化 */ + private initialize() { + this.elements.fill(null as any, 0, this.elements.length - 1); + } + + /* 新增和删除 */ + public set(key: number, val: string | null) { + this.isOutOfRange(key); + if (val !== null) { + this.elements[key] = new Entry(key, val); + } + this.elements[key] = null as any; + } + + /* 获取 */ + public get(key: number): string { + return this.elements[key].val; + } + + public entrySet() { + let arr = []; + for (let i = 0; i < this.elements.length; i++) { + if (this.elements[i] !== null) { + arr.push(this.elements[i]); + } + } + return arr; + } + + public valueSet() { + let arr = []; + for (let i = 0; i < this.elements.length; i++) { + if (this.elements[i] !== null) { + arr.push(this.elements[i].val); + } + } + return arr; + } + + public keySet() { + let arr = []; + for (let i = 0; i < this.elements.length; i++) { + if (this.elements[i] !== null) { + arr.push(this.elements[i].key); + } + } + return arr; + } + + private isOutOfRange(key: number) { + if (key > this.elements.length - 1) { + throw new Error('Out of array range'); + } + } + } ``` === "C" diff --git a/hello-algo.iml b/hello-algo.iml new file mode 100644 index 000000000..0a762e4af --- /dev/null +++ b/hello-algo.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file