來自於C++程序設計的一個題目。實現一個集合類,要求實現如下4個操做。算法
向集合中添加元素,若是集合中已存在元素則不添加數組
從集合中移除元素,移除以前須要先判斷集合中元素是否存在函數
重載
+
運算符,用以實現集合的求並集運算this重載
*
運算符,用以實現集合的求交集運算設計
該問題須要模擬實現集合類,咱們可使用數組來模擬集合,因而使用int items[100]
用來存放集合中的數據。爲了實現數組的遍歷,這就須要一個整數用來表示數組中元素的個數,因而使用int number
來表示數組中元素的個數;此外,爲了實現題目的需求,設計如下四個函數:code
使用add_item(int item)
成員函數向數組中添加元素rem
使用remove_item(int item)
成員函數向數組中移除元素it
重載operator+
表示集合的求並集運算for循環
重載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); };
Set() { this->number = 0; memset(this->items,0,sizeof(items)); }
在構造函數中,咱們對數組進行初始化,聲明完數組以後,若是不進行初始化,數組元素是隨機值,在C語言中,變量不進行初始化都會被分配隨機值。爲了不這種狀況,咱們使用memset函數對數組items全部元素所有賦值爲0;同時,因爲此時數組中沒有元素,即元素個數爲0,咱們的number也應當賦值爲0.
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.
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,這樣就完成了添加元素。
寫到這裏,咱們發現,數組元素個數指示器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表示集合中元素的個數 };
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
.
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
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