STL實踐與分析--set類型
引:
map容器是鍵-值對的集合,好比人名為鍵的地址和電話號碼。相反的,set容器類型只是單純的鍵的集合。當只想知道一個鍵是否存在時,使用set容器是最合適的。
除了兩種例外情況,set容器支援大部分的map操作,包括下面幾種:
1)第10.2節列出的所有通用的容器操作。
2)表10.3描述的建構函式。
3)表10.5描述的insert操作。
4)表10.6描述的count和find操作。
5)表10.7描述的erase操作。
兩種例外包括:set不支援下標操作符,而且沒有定義mapped_type類型。在set容器中,value_type不是pair類型,而是與key_type相同的類型。
一、set容器的定義和使用
與map容器一樣,set容器的每個鍵都只對應一個元素。以一段範圍的元素初始化set對象,或在set對象中插入一組元素時,對於每個鍵,事實上都只是添加了一個元素:
vector<int> ivec; for (int i = 0;i != 10; ++i) { ivec.push_back(i); ivec.push_back(i); } set<int> iset(ivec.begin(),ivec.end()); cout << "ivec: " << ivec.size() << endl; cout << "iset: " << iset.size() << endl;
1、在set中添加元素
可以使用insert操作在set容器中添加元素:
set<string> strSet; strSet.insert("utile"); strSet.insert("world"); for (set<string>::iterator iter = strSet.begin(); iter != strSet.end(); ++iter) { cout << *iter << endl; }
另一種用法:在調用insert函數時,提供一對迭代器實參,插入其標記範圍內的所有的元素。該版本的insert函數類似於形參為一對迭代器的建構函式– 對於一個鍵,僅僅插入一個元素:
set<int> iSet; iSet.insert(ivec.begin(),ivec.end());
與map容器的操作一樣,帶有一個鍵參數的insert版本返回pair類型對象,包含一個迭代器和一個bool值,迭代器指向擁有該鍵的元素,而bool值則表明是否添加了元素。使用迭代器對的版本返回void類型。
2、從set中擷取元素
set容器不提供下標操作符。為了通過鍵從set中擷取元素,可使用find運算。如果只需簡單地判斷某個元素是否存在,同樣可以使用count運算,返回set中該鍵對應的元素個數。當然,對於set容器,count的返回值只能是1(該元素存在)或0(該元素不存在):
cout << iSet.count(1) << endl; cout << iSet.count(11) << endl; cout << *iSet.find(1) << endl; if (iSet.find(11) != iSet.end()) { cout << *iSet.find(11) << endl; }
正如不能修改map中的元素的鍵部分一樣,set中的鍵也為const。在擷取指向set中某元素的迭代器之後,只能對其進行讀操作:
set<int>::iterator iter = iSet.find(1); *iter = 11; //Error cout << *iter << endl; //OK
二、建立“單詞排除”集
第10.3.7節的程式從map對象word_count中刪除一個指定的單詞。可將這個操作擴充為刪除指定檔案中所有的單詞(即該檔案記錄的是排除集)。也即,我們的單詞統計程式只對那些不在排除集中的單詞進行統計:
void retricted_wc(ifstream &remove_file,map<string,int> &word_count){ set<string> excluded; string remove_word; while (remove_file >> remove_word) { excluded.insert(remove_word); } string word; while (cin >> word) { if (excluded.find(word) == excluded.end()) { word_count.insert(make_pair(word,1)); } }}
//原程式void retricted_wc(ifstream &remove_file,map<string,int> &word_count){ set<string> excluded; string remove_word; while (remove_file >> remove_word) { excluded.insert(remove_word); } string word; while (cin >> word) { if (!excluded.count(word)) { ++ word_count[word]; } }}
//P321 習題10.24int main(){ set<string> excluded; ifstream inFile("input"); string excl_word; while (inFile >> excl_word) { excluded.insert(excl_word); } string word; while (cin >> word) { if (excluded.count(word)) { cout << word << endl; } else { word.assign(word.begin(),word.end()-1); /**也可以使用 *word.resize(word.size()-1); */ cout << word << endl; } }}