1. 程式人生 > >c++ STL 之 set及multiset

c++ STL 之 set及multiset


 

/**
template < class T,             // set::key_type/value_type
class Compare = less<T>,        // set::key_compare/value_compare
class Alloc = allocator<T>      // set::allocator_type
		 > class set;
**/


#define VNAME(value) {cout<<(#value)<<":"<<endl;}

template<class T>
void print_elemnt(T &v)
{
	for(auto i : v)
		cout<<i<<" ";
	cout<<endl;
}


bool fncomp (int lhs, int rhs) {return lhs<rhs;}

struct classcomp {
	bool operator() (const int& lhs, const int& rhs) const
	{return lhs<rhs;}
};
void test_set(){
	//關於建構函式,可以指定比較函式,記憶體分配函式,區間賦值,拷貝構造
	set<int,classcomp> a;
	set<int> b;
	set<int> c(b);
	//set<int> d(c.begin(),c.end());
	//set<int> e(fncomp);
	
	/**
	 迭代器:begin,end,rbegin,rend及對應的const
	 set的迭代器不能與整數進行加操作,因為記憶體不是連續的,底層實現紅黑樹
	 **/

	//a.size();
	//a.max_size();
	if (a.empty())
	{
		cout<<"a is empty."<<endl;
	}

	//返回值為pair<iterator,bool>,存在導致插入失敗
	auto i = a.insert(2);
	cout<<"a insert 2 result:"<<i.second<<endl;
	a.insert(4);
	a.insert(7);
	a.insert(a.begin(),3);
	c.insert(a.begin(),a.end());

	//b.emplace(1,2,3,4);	//錯誤,一次只能插入一個元素
	b.emplace(6);
	b.emplace_hint(b.cend(),9);	//指定位置插入一個值,插入資料就會排序,所以沒啥用感覺

	VNAME(b)
	print_elemnt(b);

	a.erase(a.begin());		//刪除具體某個位置的值,返回刪除最後一個元素的下一個元素的迭代器
	a.erase(7);				//刪除值,返回為刪除的個數,這裡為0或者1
	//a.erase(first,last);	//刪除一段區間

	cout<<"size of a:"<<a.size()<<endl;
	cout<<"max_size of a :"<<a.max_size()<<endl;

	b.swap(c);		//交換內容
	VNAME(b)
	print_elemnt(b);

	//a.key_comp();			//返回鍵比較函式
	//a.value_comp();		//返回值比較函式
	auto key_iter = a.find(1);	//得到一個值所對應迭代器。不存在返回set::end()
	auto num = a.count(1);		//計算一個值出現次數,這裡為0或者1

	//說明:預設情況下lower_bound返回該元素的迭代器,
	// upper_bound返回該元素下一個元素的迭代器
	// 如果指定比較函式,lower_bound則返回comp(element,val) return false 對應元素的迭代器
	// upper_bound則返回key_comp(val,element) return true的元素的迭代器
	auto low = a.lower_bound(2);
	auto high = a.upper_bound(3);	//一般這兩個值配合erase刪除一段區間
	auto range = a.equal_range(3);	//返回值等於某一值的區間範圍,用於multiset。區間為[,)
	cout<<"lower_bound :"<<*range.first<<endl;
	cout<<"upper_bound :"<<*range.second<<endl;

	b.clear();				//清空內容

	VNAME(a)
	print_elemnt(a);
	VNAME(c)
	print_elemnt(c);
	VNAME(b)
	print_elemnt(b);

	a.insert(2);
	a.insert(1);
	a.insert(5);

	for (auto iter_i = a.begin(); iter_i != a.end();)
	{
		cout<<*iter_i<<" ";
		if (*iter_i == 2)
		{
			//a.erase(iter_i++);
			iter_i = a.erase(iter_i);
			/*這裡說明下,為什麼順序容器中必須賦值給迭代器,而不能使用自增的原因
			 *關聯容器刪除之後只是該元素對應的迭代器失效,而順序容器刪除一個元素後,後面所有元素的迭代器都失效
			 */
		}else
		{
			iter_i++;
		}
	}

	cout<<endl;
	print_elemnt(a);

	/**
	 **multiset和set功能函式類似,只不過multiset允許重複值存在
	 **/
	multiset<int> Mula;
	Mula.insert(1);
	Mula.insert(2);
	Mula.insert(3);
	Mula.insert(1);
	Mula.insert(2);

	auto it = Mula.find(1);		//返回第一個值相等元素的迭代器,也即比較函式返回false時的直對應的迭代器
	it++;
	cout<<" 1 pos "<<*it<<endl;
	//可以使用equal_range獲取相同值的範圍

	VNAME(Mula)
	print_elemnt(Mula);

	cout<<endl<<endl;
}