UNPKG

arayts

Version:

让 TypeScript 开发如丝般顺滑。ArayTS 提供了一套高效、优雅的算法工具集,包含常用的数据结构与算法实现,帮助开发者轻松构建可靠的应用程序。

384 lines (383 loc) 11.3 kB
"use strict"; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.topologicalSort = exports.Trie = exports.kmp = exports.treeTraversal = exports.TreeNode = exports.UnionFind = exports.binarySearch = exports.quickSort = exports.levenshteinDistance = exports.longestCommonSubsequence = exports.shuffle = exports.LRUCache = exports.memoize = void 0; /** * 函数记忆化 * @param fn 需要缓存的函数 */ var memoize = function (fn) { var cache = new Map(); return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var key = JSON.stringify(args); if (cache.has(key)) { return cache.get(key); } var result = fn.apply(void 0, args); cache.set(key, result); return result; }; }; exports.memoize = memoize; /** * LRU缓存 */ var LRUCache = /** @class */ (function () { function LRUCache(capacity) { this.capacity = capacity; this.cache = new Map(); } LRUCache.prototype.get = function (key) { if (!this.cache.has(key)) return undefined; var value = this.cache.get(key); this.cache.delete(key); this.cache.set(key, value); return value; }; LRUCache.prototype.put = function (key, value) { if (this.cache.has(key)) { this.cache.delete(key); } else if (this.cache.size >= this.capacity) { var firstKey = this.cache.keys().next().value; this.cache.delete(firstKey); } this.cache.set(key, value); }; return LRUCache; }()); exports.LRUCache = LRUCache; /** * 洗牌算法 */ var shuffle = function (arr) { var _a; var result = __spreadArray([], arr, true); for (var i = result.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); _a = [result[j], result[i]], result[i] = _a[0], result[j] = _a[1]; } return result; }; exports.shuffle = shuffle; /** * 最长公共子序列 */ var longestCommonSubsequence = function (text1, text2) { var dp = Array(text1.length + 1) .fill(0) .map(function () { return Array(text2.length + 1).fill(0); }); for (var i = 1; i <= text1.length; i++) { for (var j = 1; j <= text2.length; j++) { if (text1[i - 1] === text2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); } } } return dp[text1.length][text2.length]; }; exports.longestCommonSubsequence = longestCommonSubsequence; /** * 最短编辑距离(Levenshtein Distance) */ var levenshteinDistance = function (str1, str2) { var dp = Array(str1.length + 1) .fill(0) .map(function () { return Array(str2.length + 1).fill(0); }); for (var i = 0; i <= str1.length; i++) dp[i][0] = i; for (var j = 0; j <= str2.length; j++) dp[0][j] = j; for (var i = 1; i <= str1.length; i++) { for (var j = 1; j <= str2.length; j++) { if (str1[i - 1] === str2[j - 1]) { dp[i][j] = dp[i - 1][j - 1]; } else { dp[i][j] = Math.min(dp[i - 1][j] + 1, // 删除 dp[i][j - 1] + 1, // 插入 dp[i - 1][j - 1] + 1 // 替换 ); } } } return dp[str1.length][str2.length]; }; exports.levenshteinDistance = levenshteinDistance; /** * 快速排序 */ var quickSort = function (arr) { if (arr.length <= 1) return arr; var swap = function (array, i, j) { var _a; _a = [array[j], array[i]], array[i] = _a[0], array[j] = _a[1]; }; var partition = function (array, low, high) { var pivot = array[high]; // 使用数组最后一个元素作为基准值 var i = low - 1; for (var j = low; j < high; j++) { if (array[j] <= pivot) { i++; swap(array, i, j); } } swap(array, i + 1, high); return i + 1; }; var quickSortHelper = function (array, low, high) { if (low < high) { var pivotIndex = partition(array, low, high); quickSortHelper(array, low, pivotIndex - 1); // 左侧子数组 quickSortHelper(array, pivotIndex + 1, high); // 右侧子数组 } }; var arrCopy = __spreadArray([], arr, true); // 避免修改原数组 quickSortHelper(arrCopy, 0, arrCopy.length - 1); return arrCopy; }; exports.quickSort = quickSort; /** * 二分查找 * @returns 目标值的索引,未找到返回-1 */ var binarySearch = function (arr, target) { var left = 0; var right = arr.length - 1; while (left <= right) { var mid = Math.floor((left + right) / 2); if (arr[mid] === target) return mid; if (arr[mid] < target) left = mid + 1; else right = mid - 1; } return -1; }; exports.binarySearch = binarySearch; /** * 并查集 */ var UnionFind = /** @class */ (function () { function UnionFind(size) { this.parent = Array.from({ length: size }, function (_, i) { return i; }); this.rank = Array(size).fill(0); } UnionFind.prototype.find = function (x) { if (this.parent[x] !== x) { this.parent[x] = this.find(this.parent[x]); } return this.parent[x]; }; UnionFind.prototype.union = function (x, y) { var rootX = this.find(x); var rootY = this.find(y); if (rootX !== rootY) { if (this.rank[rootX] < this.rank[rootY]) { this.parent[rootX] = rootY; } else if (this.rank[rootX] > this.rank[rootY]) { this.parent[rootY] = rootX; } else { this.parent[rootY] = rootX; this.rank[rootX]++; } } }; UnionFind.prototype.connected = function (x, y) { return this.find(x) === this.find(y); }; return UnionFind; }()); exports.UnionFind = UnionFind; /** * 二叉树节点 */ var TreeNode = /** @class */ (function () { function TreeNode(value, left, right) { if (left === void 0) { left = null; } if (right === void 0) { right = null; } this.value = value; this.left = left; this.right = right; } return TreeNode; }()); exports.TreeNode = TreeNode; /** * 二叉树遍历 */ exports.treeTraversal = { preorder: function (root) { var result = []; var traverse = function (node) { if (!node) return; result.push(node.value); traverse(node.left); traverse(node.right); }; traverse(root); return result; }, inorder: function (root) { var result = []; var traverse = function (node) { if (!node) return; traverse(node.left); result.push(node.value); traverse(node.right); }; traverse(root); return result; }, postorder: function (root) { var result = []; var traverse = function (node) { if (!node) return; traverse(node.left); traverse(node.right); result.push(node.value); }; traverse(root); return result; } }; /** * KMP字符串匹配 * @returns 模式串在文本串中的起始位置,未找到返回-1 */ var kmp = function (text, pattern) { if (pattern.length === 0) return 0; // 构建next数组 var next = [0]; for (var i = 1, j = 0; i < pattern.length; i++) { while (j > 0 && pattern[i] !== pattern[j]) { j = next[j - 1]; } if (pattern[i] === pattern[j]) { j++; } next[i] = j; } // 匹配 for (var i = 0, j = 0; i < text.length; i++) { while (j > 0 && text[i] !== pattern[j]) { j = next[j - 1]; } if (text[i] === pattern[j]) { j++; } if (j === pattern.length) { return i - j + 1; } } return -1; }; exports.kmp = kmp; /** * Trie(前缀树) */ var Trie = /** @class */ (function () { function Trie() { this.root = {}; } Trie.prototype.insert = function (word) { var node = this.root; for (var _i = 0, word_1 = word; _i < word_1.length; _i++) { var char = word_1[_i]; if (!node[char]) { node[char] = {}; } node = node[char]; } node.isEnd = true; }; Trie.prototype.search = function (word) { var node = this.traverse(word); return node !== null && node.isEnd === true; }; Trie.prototype.startsWith = function (prefix) { return this.traverse(prefix) !== null; }; Trie.prototype.traverse = function (str) { var node = this.root; for (var _i = 0, str_1 = str; _i < str_1.length; _i++) { var char = str_1[_i]; if (!node[char]) { return null; } node = node[char]; } return node; }; return Trie; }()); exports.Trie = Trie; /** * 拓扑排序(Kahn算法) * @param graph 邻接表表示的有向图 * @returns 拓扑排序结果,如果存在环则返回空数组 */ var topologicalSort = function (graph) { var inDegree = new Map(); var result = []; var queue = []; // 初始化入度 // 使用 Array.from() 遍历 Map Array.from(graph.entries()).forEach(function (_a) { var node = _a[0], neighbors = _a[1]; if (!inDegree.has(node)) { inDegree.set(node, 0); } neighbors.forEach(function (neighbor) { inDegree.set(neighbor, (inDegree.get(neighbor) || 0) + 1); }); }); // 将入度为0的节点加入队列 // 使用 Array.from() 将 Map 转换为数组进行遍历 Array.from(inDegree.entries()).forEach(function (_a) { var node = _a[0], degree = _a[1]; if (degree === 0) { queue.push(node); } }); // BFS while (queue.length > 0) { var node = queue.shift(); result.push(node); if (graph.has(node)) { for (var _i = 0, _a = graph.get(node); _i < _a.length; _i++) { var neighbor = _a[_i]; inDegree.set(neighbor, inDegree.get(neighbor) - 1); if (inDegree.get(neighbor) === 0) { queue.push(neighbor); } } } } return result.length === inDegree.size ? result : []; }; exports.topologicalSort = topologicalSort;