JavaScript數據結構與算法之 "集合"

  • 昨天實現的集合有一些bug,這次重寫了代碼。

集合數據結構

  • 集合是由一組無序且唯一(即不重複)的項組成
  • 空集:空集是不包含任何元素的集合
  • 可以把集合想象成一個既沒有重複元素,也沒有順序概念的數組
  • 集合在計算機領域中的運用
    • 集合在計算機科學中的主要應用之一是數據庫
    • 集合被用於數據庫查詢的設計和處理
    • 當我們執行數據庫的查詢語句時,使用的就是集合運算,並且數據庫也會返回一個數據集合
  • 集合的運算
    • 並集:對於給定的兩個集合,返回一個包含兩個集合中所有元素的新集合
    • 交集:對於給定的兩個集合,返回一個包含兩個集合中共有的元素的新集合
    • 差集:對於給定的兩個集合,返回一個包含所有存在於第一個集合但不存在於第二個集合中的元素組成的新集合
    • 子集:驗證一個給定的集合中的元素是否都存在於另一個集合中

使用對象實現集合

  • 將參數轉換爲字符串

    /*將傳入的參數轉換爲字符串*/
    const toStr = (param) => {
        if (param === null) {
            return 'NULL';
        } else if (param === undefined) {
            return 'UNDEFINED';
        } else if (typeof param === 'number' || param instanceof Number) {
            return `${param}`;
        } else if (typeof param === 'string' || param instanceof String) {
            return `${param}`;
        } else if (typeof param === 'symbol') {
            return param;
        } else {
            return JSON.stringify(param);
        }
    };
    
  • 方法

    • add(element):向集合中添加一個新元素
    • delete(element):從集合中刪除一個元素
    • has(element):判斷元素是否存在於集合中,存在返回true,不存在返回false
    • clear():刪除集合中所有的元素
    • size():返回集合中所有元素的數量。它與數組的length屬性類似
    • values():返回由集合中所有元素構成的數組
    • union(otherSet):返回當前集合和另一個集合的並集
    • intersection(otherSet):返回當前集合和另一個集合的交集
    • difference(otherSet):返回當前集合和另一個集合的差集
    • isSubsetOf(otherSet):判斷當前集合是否是另一個集合的子集
  • 代碼

    /*創建集合的類*/
    class Set {
        constructor() {
            this.items = {};  // 存儲集合元素的對象
        }
    
        // add(element):向集合中添加一個新元素
        add(element) {
            if (this.has(element)) { // element在集合中
                return false;
            }
    
            const key = toStr(element);
            this.items[key] = element;
            return true;
        }
    
        // delete(element):從集合中刪除一個元素
        delete(element) {
            if (this.has(element)) { // element在集合中
                const key = toStr(element);
                delete this.items[key];
                return true;
            }
    
            return false;
        }
    
        // has(element):判斷元素是否存在於集合中,存在返回true,不存在返回false
        has(element) {
            const key = toStr(element);
            return Object.prototype.hasOwnProperty.call(this.items, key);
        }
    
        // clear():刪除集合中所有的元素
        clear() {
            this.items = {};
        }
    
        // size():返回集合中所有元素的數量。它與數組的length屬性類似
        size() {
            return Object.keys(this.items).length;
        }
    
        // values():返回由集合中所有元素構成的數組
        values() {
            return Object.values(this.items);
        }
    
        // union(otherSet):返回當前集合和另一個集合的並集
        union(otherSet) {
            const newSet = new Set();
    
            this.values()
                .concat(otherSet.values())
                .forEach((v) => newSet.add(v));
    
            return newSet;
        }
    
        // intersection(otherSet):返回當前集合和另一個集合的交集
        intersection(otherSet) {
            const newSet = new Set();
    
            // 找到元素最多的集合
            let bigSet = this;
            let smallSet = otherSet;
    
            if (bigSet.values().length < smallSet.values().length) { // 如果bigSet中的元素數量小於smallSet中元素的數量
                bigSet = otherSet;
                smallSet = this;
            }
    
            smallSet.values()
                .filter((v) => bigSet.has(v))
                .forEach((v) => newSet.add(v));
    
            return newSet;
        }
    
        // difference(otherSet):返回當前集合和另一個集合的差集
        difference(otherSet) {
            const newSet = new Set();
    
            this.values()
                .filter((v) => !otherSet.has(v))
                .forEach((v) => newSet.add(v));
    
            return newSet;
        }
    
        // isSubsetOf(otherSet):判斷當前集合是否是另一個集合的子集
        isSubsetOf(otherSet) {
            if (this.size() > otherSet.size()) { //如果當前集合中的元素大於另一個集合中的元素
                return false;
            }
    
            return this.values().every((v) => otherSet.has(v));
        }
    
    }
    
  • 集合的使用

    const set1 = new Set();
    set1.add(1);
    set1.add({});
    set1.add(undefined);
    set1.add(undefined);
    set1.add(null);
    set1.add(null);
    set1.add({a:'李四'});
    
    const set2 = new Set();
    set2.add(1);
    set2.add(2);
    set2.add([1]);
    set2.add(['a','b','c']);
    set2.add(undefined);
    
    console.log(set1.values());
    console.log(set1.union(set2).values());
    console.log(set1.intersection(set2).values());
    console.log(set1.difference(set2).values());
    console.log(set1.isSubsetOf(set2));
    
    // 結果
    // [ 1, {}, undefined, null, { a: '李四' } ]
    // [ 1, 2, {}, undefined, null, { a: '李四' }, [ 1 ], [ 'a', 'b', 'c' ] ]
    // [ 1, undefined ]
    // [ {}, null, { a: '李四' } ]
    // false
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章