1. 程式人生 > 其它 >學習JavaScript演算法與資料結構第三版第7章 集合

學習JavaScript演算法與資料結構第三版第7章 集合

技術標籤:資料結構與演算法資料結構javascript

集合

集合是有一組無序且唯一(不能重複)的項組成。



集合分為交集、並集、差集、子集

class Set {
    constructor(props) {
        this.items = {};
    };
    //判斷某個元素是否存在在集合中
   /* has(element){
        return element in this.items;
    }*/
    //更好的方法
    has(element){
        return Object.prototype.hasOwnProperty.call(this.items,element);
    };

    //新增方法
    add(element){
        if(!this.has(element)){
            this.items[element] = element;//1
            return true;
        }
        return false;
    };

    delete(element){
        if(this.has(element)){
            delete this.items[element];
            return true;
        }
        return false;
    };

    clear(){
        this.items = {};
    };
    //ES6 內建方法
    size(){
        return Object.keys(this.items).length;
    };
    sizeLegacy(){
        let count = 0;
        for (let key in this.items) {
            if (this.items.hasOwnProperty(key)){
                count++;
            }
        }
        return count;
    };
    values(){
        return Object.values(this.items);//返回一個給定物件所有值的陣列
    };

    valuesLegacy(){
        let values = [];
        for (let key in this.items) {
            if(this.items.hasOwnProperty(key)){
                values.push(key);
            }
        }
        return values
    };

    //實現並集的程式碼 使用ES2015 引入的forEach 方法。
    union(otherSet){
        const unionSet = new Set();
        this.values().forEach(value => unionSet.add(value));
        otherSet.values().forEach(value => unionSet.add(value));
        return unionSet;
    };
   /* //ES6 之前的程式碼
    union(otherSet){
        const unionSet = new Set();
        let values = this.values();
        for(let i = 0; i < values.length; i++){
            unionSet.add(values[i]);
        }
        values = otherSet.values();
        for(let i = 0; i < values.length; i++){
            unionSet.add(values[i]);
        }

        return otherSet;
    };*/
    //交集
/*
    intersection(otherSet){
        const intersection = new Set();
        let values = this.values();
        for (let i = 0; i < values.length; i++) {
            if(otherSet.has(values[i])){
                intersection.add(values[i]);
            }
        }
        return intersection;
    };*/

    //交集程式碼優化
    intersection(otherSet){
        const values = this.values();
        const otherValues = otherSet.values();
        const intersectionSet = new Set();
        let biggerSet = values;
        let smallerSet = otherSet;
        if (otherValues.length-values.length > 0){
            biggerSet = otherValues;
            smallerSet = values;
        }

        smallerSet.forEach(value => {
            if (biggerSet.includes(value)){
                intersectionSet.add(value);
            }
        });
        return intersectionSet;
    };

    //差集程式碼

    difference(otherSet){
        const differenceSet = new Set();
        this.values().forEach(value => {
            if (!otherSet.has(value)){
                differenceSet.add(value);
            }
        });
        return differenceSet;
    };
    isSubsetOf(otherSet){
        if(this.size() > otherSet.size()){
            return false;
        }
        let isSubSet = true;
        this.values().every(value => {
            if(!otherSet.has(value)){
                isSubSet = false;
                return false;
            }
            return true;
        });
        return isSubSet;
    }
}
//測試
/*const set = new Set();
set.add(1);
console.log(set.values());
console.log(set.has(1));
console.log(set.size());

set.add(2);
console.log(set.values());
console.log(set.has(2));
console.log(set.size());

set.delete(1);
console.log(set.values());

set.delete(2);
console.log(set.values());*/

//測試並集程式碼
/*
const setA = new Set();
setA.add(1);
setA.add(2);
setA.add(3);


const setB = new Set();
setB.add(3);
setB.add(4);
setB.add(5);
setB.add(6);

const setAB = setA.union(setB);
console.log(setAB.values());*/

//檢驗子集程式碼
const setA = new Set();
setA.add(1);
setA.add(2);

const setB = new Set();
setB.add(1);
setB.add(2);
setB.add(3);


const setC = new Set();
setC.add(2);
setC.add(3);
setC.add(4);

console.log(setA.isSubsetOf(setB));
console.log(setA.isSubsetOf(setC));


原生set程式碼

const set = new Set();
set.add(1);
console.log(set.values());
console.log(set.has(1));
console.log(set.size);

const setA = new Set();
setA.add(1);
setA.add(2);

const setB = new Set();
setB.add(1);
setB.add(2);
setB.add(3);
setB.add(4);

//1. 模擬並集

const union = (setA,setB) => {
    const unionAB = new Set();
    setA.forEach(value => unionAB.add(value));
    setB.forEach(value => unionAB.add(value));
    return unionAB;
};

console.log(union(setA,setB));

//模擬交集


const intersection = (setA,setB) => {
    const unionAB = new Set();
    setA.forEach(value => unionAB.add(value));
    setB.forEach(value => unionAB.add(value));
    return unionAB;
};
//模擬差集
const difference = (setA,setB) =>{
    const  differenceSet  = new Set();
    setA.forEach(value => {
        if(!setB.has(value)){
            differenceSet.add(value);
        }
    });
    return differenceSet;
};
//ES2015支援向建構函式傳遞一組陣列來初始化集合的運算
console.log(new Set([...setA].filter(x => setB.has(x))));//交際
console.log(new Set([...setB].filter(x => !setA.has(x))));//差集B-A
console.log(new Set([...setB]));