數據結構JavaScript——集合

在數據結構之前,集合首先是個非常重要的數學概念,離散數學的第一課應該都是講集合吧。。。


在數據結構中,集合是由一組無序且唯一的項組成的。這裏對這種數據結構進行了封裝,使用對象來存儲項(鍵和值都爲該項自身),提供了添加項、刪除項等一系列基本的集合操作方法。並在構造器對象上定義了求兩集合並集、交集、差集、笛卡爾積、環積的方法,以及判斷是否爲子集、真子集、同一集合的方法。  關於構造器對象上定義的這些方法,大家可以將它添加至原型對象中並進行相應修改,使得可以自動將調用對象作爲方法的第一個參數。 這裏還支持鏈式調用。 各方法功能見代碼註釋:

//set  
function Set(){  
    //私有變量  
    var items = {},  
        size = 0;  


    //向集合中添加元素  Object(Set)  
    this.add = function(value){  
        if(!this.has(value)){  
            items[value] = value;  
            size++;  
            return this;  
        }  
        throw 'Set.add() false';  
        return false;  
    };  
    //從集合中移除元素 Object(Set)  
    this.remove = function(value){  
        if(this.has(value)){  
            delete items[value];  
            size--;  
            return this;  
        }  
        throw 'Set.remove() false';  
        return false;  
    };  
    //集合中是否存在該元素 Boolean  
    this.has = function(value){  
        return items.hasOwnProperty(value);  
    };  
    //清空集合 true  
    this.clear = function(){  
        items = {};  
        size = 0;  
        return true;  
    };  
    //集合大小 Number  
    this.size = function(){  
        return size;  
    };  
    //集合中的元素列表 Object(Array)  
    this.values = function(){  
        return Object.keys(items);  
    };
} 
//在構造器對象上定義了一系列集合運算方法 可以直接調用  
//求交集 Object(Set)  
Set.intersection = function(set1, set2){  
    var res = new Set(),  
        temp = set1.values();  
    for(var i in temp){  
        if(set2.has(temp[i]))   
            res.add(temp[i]);  
    }  
    return res;  
}  
//求並集 Object(Set)  
Set.union = function(set1, set2){  
    var res = new Set(),  
        temp = set1.values(),  
        temp2 = set2.values();  
    for(var i in temp)   
        res.add(temp[i]);  
    for(var j in temp2)   
        res.add(temp2[j]);  
  
    return res;  
}  
//求差集set1-set2 Object(Set)  
Set.difference = function(set1, set2){  
    var res = new Set(),  
        temp = set1.values();  
    for(var i in temp)  
        if(!set2.has(temp[i]))   
            res.add[temp[i]];  
      
    return res;  
}  
//求笛卡兒積 這裏用數組表示序偶 Object(Set)  
Set.cartesianProduct = function(set1,set2){  
    var res = new Set(),  
        temp1 = set1.values(),  
        temp2 = set2.values();  
    for(var i = 0; i < temp1.length;i++)  
        for(var j = 0;j < temp2.length;j++)  
            res.add([temp1[i],temp2[j]]);  
    return res;  
}  
//求對稱差 Object(Set)  
Set.symmetricDifference = function(set1, set2){  
    return Set.union(Set.difference(set1, set2),Set.difference(set2,set1));  
}  
//set1是否是set2的子集 Boolean  
Set.isSubset = function(set1, set2){ // if set1 is set2's subset, return true  
    var temp = set1.values();  
    for(var i in temp)  
        if(!set2.has(temp[i]))   
            return false;  
    return true;  
}  
//set1是否是set2的真子集 Boolean  
Set.isProperSubset = function(set1, set2){ // if set1 is set2's proper subset, return true  
    if(set1.size() >= set2.size())   
        return false;  
    return Set.isSubset(set1, set2);  
  
    //another   
    //return Set.isSubset(set1, set2) && !Set.equality(set1, set2);  
}  
//兩集合是否相等  
Set.equality = function(set1, set2){  
    return Set.isSubset(set1, set2) && Set.isSubset(set2, set1);  
}  

其實在寫面向對象系列後,有點小強迫症,特別想把方法都寫進原型對象裏。但是這裏因爲要通過閉包實現私有變量,必須將方法放進構造函數中。 如果非要把方法寫在原型對象裏的話,構造函數裏也得定義對私有變量的訪問接口方法,那感覺就真有點畫蛇添足了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章