我正在编写一款参考 C++STL 的 javascript 标准数据结构库,希望能与 LeetCode 合作
8163
2022.07.26
2022.07.26
发布于 未知归属地

What is it

js-sdsl - 一款参考 C++ STL 编写的 JavaScript 数据结构库

内含使用 RB-tree 实现的 Set,Map 以及哈希表、优先队列等多种数据结构,拥有极度完整的单元测试和性能测试以及完整的 api 文档

支持 CommonJS 和 ES modules,同时支持浏览器 script 标签引入,采用 TypeScript 编写,具有严谨的类型推导

Why it

尽管 JavaScript 出现了很多年,但是一直没有一套标准的库来实现或包含高级数据结构,这对一种语言来说是不幸的事件,我们想通过编写这个库来弥补这一缺陷

对于 LeetCode 的用户来说,如果你是一位前端开发人员(例如我),有了它后不必再去学习新的语言,例如 C++、Java 或 Python,而可以通过这个库来更高效率的在 LeetCode 上学习

Examples

215.数组中的第K个最大元素

这道题想必大家都不陌生,使用堆/优先队列可以完美的完成它,不过如果你是 Js 或 Ts 的使用者,你会发现无法使用原生的功能来实现,通过使用 js-sdsl 我们可以轻松的解决它,就像这样

import { PriorityQueue } from "js-sdsl";
function findKthLargest(nums: number[], k: number): number {
    const que = new PriorityQueue(nums);
    while (--k) que.pop();
    return que.top();
};

我们来看一道更复杂的题目,第 303 场周赛的 C 题

2353.设计食物评分系统

显然这道题可以使用哈希表和排序树进行求解,可惜的是 Js 并不提供平衡树相关的数据结构,而使用 js-sdsl 可以很好的解决这一问题,例如

import { HashMap, OrderedSet } from "js-sdsl";
class FoodRatings {
    private foodMap: HashMap<string, [number, string]>;
    private CuisineMap: HashMap<string, OrderedSet<[number, string]>>;

    constructor(foods: string[], cuisines: string[], ratings: number[]) {
        // define the compare function
        const cmp = (foodX: [number, string], foodY: [number, string]) => {
            if (foodX[0] < foodY[0]) return 1;
            if (foodX[0] > foodY[0]) return -1;
            const len = Math.min(foodX[1].length, foodY[1].length);
            for (let i = 0; i < len; ++i) {
                if (foodX[1][i] < foodY[1][i]) return -1;
                if (foodX[1][i] > foodY[1][i]) return 1;
            }
            return 0;
        };
        this.foodMap = new HashMap();
        this.CuisineMap = new HashMap();
        // init our map
        cuisines.forEach((cuisine, index) => {
            this.foodMap.setElement(foods[index], [ratings[index], cuisine]);
            const set = this.CuisineMap.getElementByKey(cuisine);
            if (set === undefined) {
                this.CuisineMap.setElement(cuisine, 
                    new OrderedSet([
                        [ratings[index], foods[index]
                    ] as [number, string]], cmp));
            } else {
                set.insert([ratings[index], foods[index]]);
            }
        });
    }

    changeRating(food: string, newRating: number): void {
        const [rating, cuisine] = this.foodMap.getElementByKey(food) as [number, string];
        const set = this.CuisineMap.getElementByKey(cuisine);
        this.foodMap.setElement(food, [newRating, cuisine]);
        set?.eraseElementByKey([rating, food]);
        set?.insert([newRating, food]);
    }

    highestRated(cuisine: string): string {
        // @ts-ignore
        // there may get undefined, but this question is guaranteed to have an answer.
        return this.CuisineMap.getElementByKey(cuisine)?.getElementByPos(0)?.[1];
    }
}

const foodRatings = new FoodRatings(["kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"], ["korean", "japanese", "japanese", "greek", "japanese", "korean"], [9, 12, 8, 15, 14, 7]);
console.log(foodRatings.highestRated("korean"));
console.log(foodRatings.highestRated("japanese"));
foodRatings.changeRating("sushi", 16);
console.log(foodRatings.highestRated("japanese"));
foodRatings.changeRating("ramen", 16);
console.log(foodRatings.highestRated("japanese"));

/*
 * kimchi
 * ramen
 * sushi
 * ramen
 */

What we want

在这里发帖的原因有两个:

  1. 邀请更多的 JS/TS 或其他的开发者对 js-sdsl 提供开发建议,以便于我们提升库的性能
  2. 希望得到 LeetCode 官方的支持,将 js-sdsl 引入到代码中,提供给 LeetCode 用户使用

如果 LeetCode 官方有幸能看到这一建议并且愿意尝试的话,我们会非常荣幸与您合作!

Project link

最后附上项目地址:

github 链接:https://github.com/ZLY201/js-sdsl
npm 链接:https://www.npmjs.com/package/js-sdsl

评论 (36)