1. 程式人生 > 實用技巧 >STL學習筆記-不同容器的操作

STL學習筆記-不同容器的操作

1,deque類

deque與vector類似,是一個動態陣列,與vector不同的是它可以在陣列的開頭和結尾插入和刪除資料

#include<iostream>
#include<deque>
#include<algorithm>

int main()
{
	std::deque<int> d;
	//隊尾插入資料
	d.push_back(3); d.push_back(4); d.push_back(5);
	//隊首插入資料
	d.push_front(2); d.push_front(1); d.push_front(0);
	for (int i = 0; i < d.size(); ++i)
	{
		std::cout << "d[" << i << "] = " << d[i] << std::endl;
	}
	d.pop_back();
	d.pop_front();
	std::cout << "after pop:" << std::endl;
	std::deque<int>::iterator it;
	for (it = d.begin(); it != d.end(); ++it)
	{
		int i = distance(d.begin(), it);  // <==> i = (it - d.begin()); distance函式在algorithm中
		std::cout << "d[" << i << "] = " << d[i] << std::endl;
	}
	//system("pause");
	return 0;
}

2,list類

list是雙向連結串列,和陣列相比,在任何地方插入元素都非常快,插入時間是固定的,不會隨著資料的增多而變長。
//const_iterator不能改變其所指向的元素的值,而iterator可以。

#include<iostream>
#include<list>

void printList(std::list<int> lst)
{
	std::cout << "[ ";
	for (std::list<int>::const_iterator con_it = lst.begin(); con_it != lst.end(); ++con_it)
		std::cout << *con_it << " ";
	std::cout << "]" << std::endl;
}

int main()
{
	std::list<int> lst;
	//插入元素:
	lst.push_back(3); lst.push_back(4); lst.push_back(5);
	lst.push_front(2); lst.push_front(1); lst.push_front(0);
	//操作結果: [0 1 2 3 4 5]
	printList(lst);
	//--------------- insert插入 -------------------
	std::list<int>::iterator it;
	it = lst.begin(); ++it; ++it;
	//在it所指示的位置插入33
	lst.insert(it, 33);           //操作結果: [ 0 1 33 2 3 4 5 ]
	printList(lst);
	//1,在開頭插入2個20
	lst.insert(lst.begin(), 2, 20);  //操作結果: [ 20 20 0 1 33 2 3 4 5 ]
	printList(lst);
	//2,在末尾插入10
	lst.insert(lst.end(), 10);  //操作結果: [ 20 20 0 1 33 2 3 4 5 10 ]
	printList(lst);
	std::list<int> lst2;
	lst2.push_back(100); lst2.push_back(200); lst2.push_back(300);
	//3, insert(插入的位置,插入的區間起點,插入的區間終點)
	lst.insert(lst.end(), lst2.begin(), --lst2.end());  //操作結果: [ 20 20 0 1 33 2 3 4 5 10 100 200 ]
	printList(lst);

	//--------------- erase刪除 -------------------
	lst.erase(++lst.begin());
	lst.erase(--lst.end());  //操作結果: [ 20 0 1 33 2 3 4 5 10 100 ]
	printList(lst);
	it = lst.begin(); ++it; ++it; ++it;
	lst.erase(lst.begin(), it);  //操作結果: [ 33 2 3 4 5 10 100 ]
	printList(lst);

	//--------------- reverse反轉 -------------------
	lst.reverse();  //操作結果: [ 100 10 5 4 3 2 33 ]
	printList(lst);

	//--------------- sort排序 -------------------
	lst.sort();  //操作結果: [2 3 4 5 10 33 100 ]
	printList(lst);
	
	//system("pause");
	return 0;
}

3,satck

stack,(堆)棧,後進先出(LIFO);自適應容器(容器介面卡)不是具體的容器;無迭代器,只能在尾部操作資料。主要用在做系統軟體開發,如作業系統。
操作:s.empty(); s.size(); s.pop(); s.top(); s.push(item);

#include<iostream>
#include<vector>
#include<list>
#include<stack>

int main()
{
	//可用deque,vector, list做堆疊
	std::stack<int, std::deque<int> > stk;  //<==> 等價於 stack<int> stk; 預設用deque做堆疊
	std::stack<int, std::vector<int> > stk2;
	std::stack<int, std::list<int> > stk3;

	stk.push(1); stk.push(2); stk.push(3); stk.push(4);  //插入元素
	std::cout << "now stack size: " << stk.size() << std::endl;
	while (!stk.empty())  //當棧非空
	{
		int x = stk.top(); //獲取棧頂元素
		std::cout << x << " "; //輸出棧頂元素
		stk.pop(); //彈出棧頂元素
	}
	//system("pause");
	return 0;
}

4,queue

queue,佇列,先進先出(FIFO),容器介面卡(自適應容器),可用deque和list做,但不能用vector做。無迭代器,只能在兩端操作資料。
操作:q.empty(); q.size(); q.front(); q.back(); q.push(); q.pop();

#include<iostream>
#include<queue>
#include<list>
#include<deque>

int main()
{
	//可用deque,list做佇列,不能用vector做
	std::queue<int, std::deque<int> > q;  //<==> 等價於 queue<int> q; 預設用deque做佇列
	std::queue<int, std::list<int> > q2;
	
	q.push(1); q.push(2); q.push(3); q.push(4);  //插入元素
	std::cout << "now queue size: " << q.size() << std::endl;
	std::cout << "隊首元素:" << q.front() << std::endl;
	std::cout << "隊尾元素:" << q.back() << std::endl;
	while (q.size() != 0)
	{
		std::cout << "新隊首元素:" << q.front() << std::endl;
		q.pop();
	}
	if (q.empty())
		std::cout << "佇列已空!" << std::endl;

	//system("pause");
	return 0;
}

priority_queue

priority_queue,自適應容器,不能使用list;最大、最小優先順序佇列。
操作:pq.empty(); pq.size(); pq.front(); pq.back(); pq.push(); pq.pop();

#include<iostream>
#include<queue>

int main()
{
	//可用deque,list做佇列,不能用vector做
	std::priority_queue<int, std::vector<int> > pq;  //<==> 等價於 priority_queue<int> q; 預設用vector做佇列
	std::priority_queue<int, std::vector<int>, std::less<int> > pq_upper; //預設最大值優先順序佇列,與上面等價;less<int>謂詞
	std::priority_queue<int, std::vector<int>, std::greater<int> > pq_low; //最小值優先順序佇列;greater<int>謂詞
	std::priority_queue<int, std::deque<int> > pq2;
	
	pq.push(5); pq.push(10); pq.push(-1); pq.push(20);
	std::cout << "now priority_queue size: " << pq.size() << std::endl;
	while (!pq.empty())
	{
		std::cout << "新隊首元素:" << pq.top() << std::endl;
		pq.pop();
	}
	std::cout << "--------最小值優先順序佇列--------" << std::endl;
	pq_low.push(5); pq_low.push(10); pq_low.push(-1); pq_low.push(20);
	std::cout << "now priority_queue size: " << pq_low.size() << std::endl;
	while (!pq_low.empty())
	{
		std::cout << "新隊首元素:" << pq_low.top() << std::endl;
		pq_low.pop();
	}
	//system("pause");
	return 0;
}

5,map和multimap

map和multimap(對映/字典/關聯陣列),內部結構:紅黑樹。map中的鍵不允許重複,若重複,最先插入的鍵值對有效;multimap中鍵可以重複。
基本操作:insert; count和find; erase

#include<iostream>
#include<map>
#include<string>

void printMultimap(std::multimap<int, std::string> mmp)
{
	for (std::map<int, std::string>::const_iterator it = mmp.begin(); it != mmp.end(); ++it)
		std::cout << "key: " << it->first << ", value: " << it->second.c_str() << std::endl;
	std::cout << "----------------------------------" << std::endl;
}

int main()
{
	std::map<int, std::string> mp;
	std::multimap<int, std::string> mmp;

	mp.insert(std::map<int, std::string>::value_type(1, "One"));
	mp.insert(std::make_pair(-1, "Minus One"));
	mp.insert(std::pair<int, std::string>(1000, "One-Thousand"));
	mp.insert(std::pair<int, std::string>(1000, "One_Thousand")); //map元素的鍵(key)不允許重複,重複的不會插入;
	mp[1000000] = "One Million";
	std::cout << "The map size: " << mp.size() << std::endl;
	std::cout << "map 資料:\n";
	for (std::map<int, std::string>::const_iterator it = mp.begin(); it != mp.end(); ++it)
	{
		std::cout << "key: " << it->first << ", value: " << it->second.c_str() << std::endl;
	}
	std::cout << "map簡單查詢mp[1000] = " << mp[1000] << std::endl;
	std::cout << "----------multimap------------" << std::endl;

	mmp.insert(std::multimap<int, std::string>::value_type(1, "One"));
	mmp.insert(std::multimap<int, std::string>::value_type(10, "Ten"));
	mmp.insert(std::multimap<int, std::string>::value_type(10, "Ten"));
	mmp.insert(std::make_pair(-1, "Minus One"));
	mmp.insert(std::pair<int, std::string>(1000, "One Thousand"));
	mmp.insert(std::pair<int, std::string>(1000, "One Thousand"));
	mmp.insert(std::pair<int, std::string>(1000, "One_Thousand"));
	mmp.insert(std::pair<int, std::string>(1000, "One-Thousand"));
	//mmp[1000000] = "One Million";  multimap不能用這種方式插入元素
	std::cout << "The multimap size: " << mmp.size() << std::endl;  //內部結構紅黑樹,查詢非常快。
	std::cout << "multimap 資料:\n";
	printMultimap(mmp);

	std::cout << "multimap中有" << mmp.count(1000) << "個1000:" << std::endl;  //count計數

	std::multimap<int, std::string>::const_iterator cit;  //find查詢
	cit = mmp.find(1000);
	for (int i = 0; i < mmp.count(1000); ++i)
	{
		std::cout << "  " << cit->first << " : " << cit->second << std::endl;
		cit++;
	}

	if (mmp.erase(-1) > 0)  //erase刪除,若刪除成功,返回結果大於0;
		std::cout << "刪除-1後剩餘元素:" << std::endl;
	printMultimap(mmp);

	if (mmp.find(10) != mmp.end())
	{
		mmp.erase(10);  //不管對應的鍵值對有多少個,直接全部刪除
		std::cout << "刪除10後剩餘元素:" << std::endl;
	}
	printMultimap(mmp);

	mmp.erase(mmp.lower_bound(1000), mmp.upper_bound(1000));
	std::cout << "刪除1000後剩餘元素:" << std::endl;
	printMultimap(mmp);

	//system("pause");
	return 0;
}

6,set和multiset

set和multiset,set中的元素不允許重複,而multiset可以。資料結構,紅黑樹;插入(稍慢),查詢和刪除的速度都非常快。若有大量的資料,建議優先放set中,放入其中的資料會自動進行排序,且其中的元素不能修改,可先刪除在插入來實現修改。
基本操作:insert; count和find; erase

#include<iostream>
#include<set>

template <typename Container>
void printSet(const Container& mset)
{
	for (Container::const_iterator con_it = mset.begin(); con_it != mset.end(); ++con_it)
		std::cout << *con_it << " ";
	std::cout << "\n------------------------------" << std::endl;
}

int main()
{
	std::set<int> st;
	std::multiset<int> mst;
	st.insert(1); st.insert(-1); st.insert(10); st.insert(10); st.insert(27); //重複元素自動過濾掉
	if (st.find(27) != st.end())  //find方法
		std::cout << "27在本set中。\n";

	std::cout << "set中的元素:";
	printSet(st);
	

	mst.insert(st.begin(), st.end());
	mst.insert(100); mst.insert(100); mst.insert(100);
	std::cout << "multiset中有 " << mst.count(100) << "個100" << std::endl;
	std::cout << "multiset中的有" << mst.size() << "個元素:";
	printSet(mst);

	mst.erase(100); //刪除元素,不管有多少個100全部刪除。
	std::cout << "刪除100後剩餘元素:";
	printSet(mst);

	mst.clear(); //清空所有元素
		std::cout << "clear後的元素個數:" << mst.size() << std::endl;

	//system("pause");
	return 0;
}