c++_stl-2


API可訪問cplusplus.com/reference

4. deque容器

deque<int> d

可翻譯爲雙端隊列,主要操作與vector類似:

  • push_back(),pop_back(),push_front(),pop_front()
  • front(),back()取頭尾元素
  • iterator find(iterator begin, iterator end, value)根據值找索引,找不到則返回end()

5. stack容器

stack<int> s

主要操作:

  • void push(),void pop()
  • bool empty(),常用語句爲while( !s.empty()){}
  • s.top()獲取棧頂元素

可嘗試練習用棧等容器存儲指針

6. queue容器

queue<int> q

主要操作和棧相同。

6.1 priority_queue

the first element is always the greatest of the elements it contains.

template <class T, class Container = vector<T>,
  class Compare = less<typename Container::value_type> >
      
/*
std::less
returns whether the its first argument compares less than the second
*/

默認最大優先級隊列.

#include<iostream>
using namespace std;
#include "queue" 
#include "functional"

int main(int argc, char *argv[])
{
	priority_queue<int> pq1;
	//priority_queue<int,vector<int>,less<int> > pq2;
	priority_queue<int,vector<int>,greater<int> > pq3;
	
	pq1.push(5);
	pq1.push(3);
	pq1.push(7);
	
	while(pq1.size())
	{
		cout<<pq1.top()<<" ";
		pq1.pop();
	}
	cout<<endl;
	
	pq3.push(5);
	pq3.push(3);
	pq3.push(7);
	while(pq3.size())
	{
		cout<<pq3.top()<<" ";
		pq3.pop();
	}
	
	cin.get();
	return 0;
}
/*
7 5 3
3 5 7
*/

7. List容器

雙向鏈表容器,不能隨機存取元素,即不支持[]at();迭代器支持it++,但不支持it+2等隨機訪問。

一些操作可以查詢API

刪除

list.clear(),清空

iterator list.erase(iterator begin, iterator end),注意左閉右開,返回後 一元素位置

iterator list.erase(iterator pos)

list.remove(elem)刪除所以該值

#include<iostream>
using namespace std;
#include "list" 

int main(int argc, char *argv[])
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);
	list<int>::iterator it1 = l.begin();
	list<int>::iterator it2 = l.begin();
	//list<int>::iterator it2 = l.begin() + 3;
	
	it2++;
	it2++;
	
	list<int>::iterator it3 = l.erase(it1,it2);
	it1 = l.begin();
	while(it1 != l.end())
	{
		cout<<*it1<<" ";
		it1++;
	}
	cout<<endl;
	
	cout<<*it3<<endl;
	
	cin.get();
	return 0;
}
/*
3 4
3
*/

8. Set和MultSet

集合採用紅黑樹這種平衡二叉樹數據結構實現,所以:

  • 不能指定插入位置
  • 不能直接存取([],at()
  • 不能直接修改元素,必須先刪除再重新添加

set支持唯一鍵值對,而multiset同一值可以出現多次。

集合自動排序,默認從小到大。

8.1 添加和刪除

#include<iostream>
using namespace std;
#include <set>
#include <functional>

int main(int argc, char *argv[])
{
	set<int> set1;
	set<int,greater<int> > set2;
	for(int i = 0 ; i < 3; i++)
	{
		int tmp = rand()%100; 
		set1.insert(tmp);
		set2.insert(tmp);
	}
	for(set<int>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
	
	for(set<int>::iterator it = set2.begin(); it != set2.end(); it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
	
	while( !set1.empty())
	{
		set1.erase(set1.begin());
	}
	while( !set2.empty())
	{
		set2.erase(set2.begin());
	}
	
	cin.get();
	return 0;
}
/*
34 41 67
67 41 34
*/

對於自定義數據類型,應使用仿函數functor和函數對象。

是使一個類的使用看上去象一個函數。其實現就是類中實現一個operator(),這個類就有了類似函數的行爲。less<T>()greater<T>()就是預定義的仿函數,包含在頭文件<functional>中。

struct greater
	{	// functor for operator>
	typedef _Ty first_argument_type;
	typedef _Ty second_argument_type;
	typedef bool result_type;

	constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator> to operands
		return (_Left > _Right);
		}
	};

8.1.1 pair

當比較的值相等時,會插入失敗,所以我們要用對組pair類型返回值判斷。

This class couples together a pair of values, which may be of different types (T1 and T2). The individual values can be accessed through its public members first and second.

set.insert() return a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the equivalent element already in the set. The pair::second element in the pair is set to true if a new element was inserted or false if an equivalent element already existed.

#include<iostream>
using namespace std;
#include "set" 
#include "functional"

class Person
{
private:
	int age;
public:
	Person(int age)
	{
		this->age = age;
	}
	int getAge()const
	{
		return this->age;
	}
};

struct greaterPerson {
	bool operator() (const Person& left, const Person& right) const
	{
		return left.getAge() > right.getAge();
	}
};

int main(int argc, char *argv[])
{
	Person p1(11), p2(22), p3(33), p4(11);
	set<Person, greaterPerson> set1;
	Person *persons[4] = { &p1,&p2,&p3,&p4 };
	pair<set<Person, greaterPerson>::iterator, bool> pair;

	for (int i = 0; i < 4; i++)
	{
		pair = set1.insert(*persons[i]);
		if (!pair.second)
		{
			printf("p%d inserted error.\n",i+1);
		}
	}

	for(set<Person, greaterPerson>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << (*it).getAge() << endl;
	}

	cin.get();
	return 0;
}

/*
p4 inserted error.
33
22
11
*/

8.2 查找

iterator set.find(elem),返回指向elem的迭代器,沒找到則返回set.end()

int set.count(elem),對於set,返回0或1;對於multiset,可能大於1.

iterator set.lower_bound(elem)返回第一個大於等於elem的迭代器

iterator set.upper_bound(elem)返回第一個大於elem的迭代器

pair<iterator,iterator> equal_range(elem)pair::first is the lower bound of the range (the same as lower_bound), and pair::second is the upper bound (the same as upper_bound). 相當於一個左閉右開區間。

9. Map和MultMap

map是標準的關聯式容器,是一個key-value對,也按紅黑樹規則排序,不能指定位置插入。

添加和刪除操作比vector快。

支持[]

map的鍵是唯一的;multimap相同鍵可出現多次,所以不支持[]

map<T1,T2> m;

9.1 添加、刪除、遍歷

幾種常用的insert()

  • pair<iterator,bool> insert (const value_type& val);
  • iterator insert (const_iterator position, const value_type& val);
  • void insert (InputIterator first, InputIterator last);
#include<iostream>
using namespace std;
#include "map"
int main(int argc, char *argv[])
{
	map<char,int> mymap;
	mymap.insert ( pair<char,int>('a',100) );
	mymap.insert ( make_pair<char,int>('b',100) );
	pair<map<char,int>::iterator,bool> mypair = mymap.insert ( map<char,int>::value_type('c',100) );
	cout<<"mypair.first:"<<mypair.first->second<<endl;
	
	mymap['d'] = 100;
 	mymap['d'] = 200;
	
	map<char,int>::iterator it = mymap.begin();
	mymap.insert (it, std::pair<char,int>('e',300));
	
	mypair = mymap.insert ( pair<char,int>('a',100) );
	cout<<"mypair.second:"<<mypair.second<<endl;
	
	map<char,int> anothermap;
	anothermap.insert(mymap.begin(),mymap.find('e'));
	
	for (it=anothermap.begin(); it!=anothermap.end(); ++it)
	   	cout << it->first << " => " << it->second << '\n';
 	 
 	while(!mymap.empty())
 	{
	 	map<char,int>::iterator it = mymap.begin();
	 	mymap.erase(it);
 	}
 	while(!anothermap.empty())
 	{
	 	map<char,int>::iterator it = anothermap.begin();
	 	anothermap.erase(it);
 	}
	cin.get();
	return 0;
}



/*
mypair.first:100
mypair.second:0
a => 100
b => 100
c => 100
d => 200
*/

這裏注意一下隊組配合迭代器的用法:mypair.first->second;

9.2 查找

和[set的查找](#8.2 查找)類似。

iterator map.find(key);

map.count(key);,結尾爲0或1;multimap可以大於1.


10. 各個容器比較

每個容器都有默認的構造函數和默認拷貝構造函數。

除了queuestack,每個容器都有可返回迭代器的函數。

大小相關函數:size(),empty()

vector deque list set/multiset map multimap
數據結構 單端數組 雙端數組 雙向鏈表 二叉樹 二叉樹 二叉樹
可隨機存取 1 1 0 0 key可以 0
查找速度 很慢 key快
添加刪除 尾端 雙端 任何位置 - - -

deque可用於排隊系統,而不是vector.

vectordeque的比較:

  • at()vetordeque快,因爲後者開頭位置不固定;
  • 大量釋放操作,vector更快;
  • 頭部的快速添加刪除是deque的優勢。

list可用於乘客的存儲。

set可用於存取個人得分。

map可按id存儲用戶。

[#8.2 查找]:

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