來自于C++程序設計的一個題目。實現一個集合類,要求實現以下4個操作。
1.向集合中添加元素,如果集合中已存在元素則不添加
2.從集合中移除元素,移除之前需要先判斷集合中元素是否存在
3.重載+運算符,用以實現集合的求并集運算
4.重載*運算符,用以實現集合的求交集運算
1.類的整體設計
該問題需要模擬實現集合類,我們可以使用數組來模擬集合,于是使用int items[100]用來存放集合中的數據。為了實現數組的遍歷,這就需要一個整數用來表示數組中元素的個數,于是使用int number來表示數組中元素的個數;此外,為了實現題目的需求,設計以下四個函數:
1).使用add_item(int item)成員函數向數組中添加元素
2).使用remove_item(int item)成員函數向數組中移除元素
3).重載operator+表示集合的求并集運算
4).重載operator*表示集合的求交集運算
由于向集合添加元素之前,必須確保集合中不存在該元素;在從集合中移除元素之前,必須確保集合中存在該元素,因此添加is_exist(int item)方法用以判斷集合中是否存在這個元素;此外為了顯示集合,添加display()方法, 基本設計如下:
class Set{public: int items[100]; //定義一個數組作為容器存放100個集合元素 int number; //定義數字i表示集合中元素的個數 //構造函數和析構函數 Set() { this->number = 0; memset(this->items,0,sizeof(items)); } //初始化方法 int init(int items[], int num); //添加元素 bool add_item(int item); //刪除元素 bool remove_item(int item); //求集合的并集 Set operator+ (Set set2); //求集合的交集 Set operator* (Set set2); //顯示集合元素 int display(); //判斷集合當中是否存在item,返回元素在集合中的位置,不存在返回-1 int is_exist(int item);};
2.構造函數
Set() { this->number = 0; memset(this->items,0,sizeof(items));}
在構造函數中,我們對數組進行初始化,聲明完數組之后,如果不進行初始化,數組元素是隨機值,在C語言中,變量不進行初始化都會被分配隨機值。為了避免這種情況,我們使用memset函數對數組items所有元素全部賦值為0;同時,由于此時數組中沒有元素,即元素個數為0,我們的number也應當賦值為0.
3.判斷數組中是否包含元素 item
int Set::is_exist(int item){ for(int i=0; i< this->number; i++) { if(this->items[i] == item) { return i; } } return -1;}
該函數用于判斷數組中是否存在item元素,如果存在就返回item元素的位置,如果不存在就返回-1. 判斷方法非常簡單,寫一個for循環從items[0]-items[number-1]一個一個進行遍歷。如果相等,直接返回i,此時i就是數組中item元素的位置;如果遍歷完整個數組之后,都沒有發現與item相等的數組元素,說明數組中不存在item這個元素,于是返回-1.
4.向數組中添加元素
bool Set::add_item(int item){ if(is_exist(item) >= 0 || this->number >= 100) { return false; } this->items[this->number] = item; this->number++; return true;}
首先判斷數組中是否存在該元素,如果存在則不能再向集合中添加元素,直接返回false,如果不存在,則向數組中的number所指向的那個位置添加該元素,然后number作為數組元素個數的指示器+1,這樣就完成了添加元素。
5.保護數組元素不被修改
寫到這里,我們發現,數組元素個數指示器this->number,對于該問題的幾個算法都起到了核心的作用,首先,我們依賴于數組元素個數指示器遍歷數組,如果number值遭到修改,會導致無法遍歷數組。舉個例子來說,當我們調用下列語句以后:
Set set1;set1.add_item(1);set1.add_item(2);set1.add_item(3);
集合set1中的數組items變為[1,2,3],數組元素個數指示器number=3,此時,如果我們還想向集合set1中添加元素20,我們需要利用number=3這個指示器,讓set1.items[number]=20,并且讓number+1以指向下一個位置,即number=4。但是如果用戶手動修改number值,比如set1.number=50;此時,我們的number就不再能指示數組元素的正確位置,從而導致以上所有算法所依賴的number失效,因此,我們需要對數組本身,以及數組元素個數指示器number進行私有化,以避免用戶隨意篡改。于是:
class Set{public: //構造函數和析構函數 Set() { this->number = 0; memset(this->items,0,sizeof(items)); } //初始化方法 int init(int items[], int num); //添加元素 bool add_item(int item); //刪除元素 int remove_item(int item); //求集合的并集 Set operator+ (Set set2); //求集合的交集 Set operator* (Set set2); //顯示集合元素 int display(); //判斷集合當中是否存在item,返回元素在集合中的位置,不存在返回-1 int is_exist(int item);private: int items[100]; //定義一個數組作為容器存放100個集合元素 int number; //定義數字i表示集合中元素的個數};
6. 從集合中移除元素
bool Set::remove_item(int item){ int pos = is_exist(item); if(pos == -1) return false; for(int i=pos; i< this->number-1; i++) { this->items[i] = this->items[i+1]; } this->number--; return true;}
首先檢查要移除的元素在結合中是否存在,如果不存在,則直接返回false;其次,定位到集合中元素的位置,然后從這個位置開始將集合中剩余的元素逐個前移,最后集合元素指示器-1,并返回true.
7. 求兩個集合的交集
Set Set::operator* (Set set2){ Set result; for(int i=0; i< this->number; i++) { if(set2.is_exist(this->items[i]) >= 0) { result.items[result.number] = this->items[i]; result.number++; } } return result;}
算法很簡單,遍歷集合A中的元素,對于A中的每一個元素判斷在集合B中是否存在,如果存在就加入到集合C當中,最后返回集合C
8. 求兩個集合的并集
Set Set::operator+ (Set set2){ Set result; for(int i=0; i<this->number; i++) { result.items[result.number] = this->items[i]; result.number++; } for(int j=0; j<set2.number; j++) { if(result.is_exist(set2.items[j]) == -1) { result.items[result.number] = set2.items[j]; result.number++; } } return result;}
首先遍歷集合A,將集合A中的元素全部加到集合C當中,然后遍歷集合B,對于B中的每一個元素,首先判斷是否在A中存在,如果不存在則將其加入到集合C中,最終返回集合C
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網
新聞熱點
疑難解答