STL标准库与泛型编程(侯捷)笔记1

2024-01-08 08:04

本文主要是介绍STL标准库与泛型编程(侯捷)笔记1,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STL标准库与泛型编程(侯捷)

本文是学习笔记,仅供个人学习使用。如有侵权,请联系删除。

参考链接

Youbute: 侯捷-STL标准库与泛型编程

B站: 侯捷 - STL

Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCodeNote/tree/master

Github:课程ppt和源码 https://github.com/ZachL1/Bilibili-plus

文章目录

  • STL标准库与泛型编程(侯捷)
    • 3 容器之分类与各种测试(一):array
    • 4 容器之分类与各种测试(二):vector
    • 5 容器之分类与各种测试(三)list, deque,stack, queue
    • 6 容器之分类与各种测试(四):set和unordered_set等
    • 7 分配器之测试
    • 后记

本节主要介绍STL容器的使用方法
STL有很多容器,大概分类如下:

■ 标准STL序列容器
:vector、string、deque和list。
■ 标准STL关联容器
:set、multiset、map和multimap。
■ 非标准序列容器
slist和rope。slist是一个单向链表,rope本质上是一个“重型”string。
■ 非标准的关联容器
hash_set、hash_multiset、hash_map和hash_multimap。所有hash开头的,在c++11里面改名为unordered,比如unordered_set。

3 容器之分类与各种测试(一):array

测试开50万大小的array,排序并且查找花费的时间。大概0.18秒。

const long ASIZE = 500000L;long get_a_target_long()
{
long target=0;cout << "target (0~" << RAND_MAX << "): ";cin >> target;return target;
}int compareLongs(const void* a, const void* b)
{return ( *(long*)a - *(long*)b );
}#include <array>
#include <iostream>
#include <ctime> 
#include <cstdlib> //qsort, bsearch, NULL
namespace jj01
{
void test_array()
{cout << "\ntest_array().......... \n";array<long,ASIZE> c;  	clock_t timeStart = clock();									for(long i=0; i< ASIZE; ++i) {c[i] = rand(); }cout << "milli-seconds : " << (clock()-timeStart) << endl;	//cout << "array.size()= " << c.size() << endl;		cout << "array.front()= " << c.front() << endl;	cout << "array.back()= " << c.back() << endl;	cout << "array.data()= " << c.data() << endl;	// 得到array起始地址long target = get_a_target_long();timeStart = clock();::qsort(c.data(), ASIZE, sizeof(long), compareLongs); // 前面加双冒号::表示全局函数
long* pItem = (long*)::bsearch(&target, (c.data()), ASIZE, sizeof(long), compareLongs); cout << "qsort()+bsearch(), milli-seconds : " << (clock()-timeStart) << endl;	//    if (pItem != NULL)cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	
}
}

4 容器之分类与各种测试(二):vector

测试vector:放入100万个元素到vector中,放入的时间大概是3秒。

vector当放入新元素的时候,如果空间不够,它会变成原来大小的两倍,即两倍增长。

#include <vector>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
#include <algorithm> 	//sort()
namespace jj02
{
void test_vector(long& value)
{cout << "\ntest_vector().......... \n";vector<string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.push_back(string(buf));     		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	//曾經最高 i=58389486 then std::bad_allocabort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;	cout << "vector.max_size()= " << c.max_size() << endl;	//1073747823cout << "vector.size()= " << c.size() << endl;		// 真正元素的个数cout << "vector.front()= " << c.front() << endl;	cout << "vector.back()= " << c.back() << endl;	cout << "vector.data()= " << c.data() << endl;cout << "vector.capacity()= " << c.capacity() << endl << endl;	//目前vector实际分配的空间有多大	string target = get_a_target_string();{timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;  if (pItem != c.end())cout << "found, " << *pItem << endl << endl;elsecout << "not found! " << endl << endl;}{timeStart = clock();sort(c.begin(), c.end());cout << "sort(), milli-seconds : " << (clock()-timeStart) << endl; timeStart = clock();	    
string* pItem = (string*)::bsearch(&target, (c.data()), c.size(), sizeof(string), compareStrings); cout << "bsearch(), milli-seconds : " << (clock()-timeStart) << endl; if (pItem != NULL)cout << "found, " << *pItem << endl << endl;elsecout << "not found! " << endl << endl;	}c.clear();test_moveable(vector<MyString>(),vector<MyStrNoMove>(), value);	
}	
}

5 容器之分类与各种测试(三)list, deque,stack, queue

使用容器list

list是双向链表,放入元素也是push_back

#include <list>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <algorithm> //find()
#include <iostream>
#include <ctime> 
namespace jj03
{
void test_list(long& value)
{cout << "\ntest_list().......... \n";list<string> c;  	
char buf[10];clock_t timeStart = clock();							for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.push_back(string(buf));    	}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;		cout << "list.size()= " << c.size() << endl;cout << "list.max_size()= " << c.max_size() << endl;    //357913941cout << "list.front()= " << c.front() << endl;	cout << "list.back()= " << c.back() << endl;		string target = get_a_target_string();		timeStart = clock();		
auto pItem = find(c.begin(), c.end(), target);						cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;		if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	timeStart = clock();		c.sort();						cout << "c.sort(), milli-seconds : " << (clock()-timeStart) << endl;		    	c.clear();test_moveable(list<MyString>(),list<MyStrNoMove>(), value);								
}	
}

使用容器forward_list

单向链表,它没有push_back,只有push_front函数

#include <forward_list>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj04
{
void test_forward_list(long& value)
{cout << "\ntest_forward_list().......... \n";forward_list<string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.push_front(string(buf));  			   		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;	cout << "forward_list.max_size()= " << c.max_size() << endl;  //536870911cout << "forward_list.front()= " << c.front() << endl;	string target = get_a_target_string();	timeStart = clock();			
auto pItem = find(c.begin(), c.end(), target);	cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;		if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	timeStart = clock();		c.sort();						cout << "c.sort(), milli-seconds : " << (clock()-timeStart) << endl;		c.clear();	 
}											 
}

使用容器slist

测试容器slist:slist也是单向链表

#include <ext\slist>	
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj10
{
void test_slist(long& value)
{cout << "\ntest_slist().......... \n";__gnu_cxx::slist<string> c;  	char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.push_front(string(buf));     		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;			
}															
}

使用容器deque

双端队列

deque底层是分段连续,但是对使用者来说是连续的。

#include <deque>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj05
{
void test_deque(long& value)
{cout << "\ntest_deque().......... \n";deque<string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.push_back(string(buf));    			 		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;		cout << "deque.size()= " << c.size() << endl;cout << "deque.front()= " << c.front() << endl;	cout << "deque.back()= " << c.back() << endl;	cout << "deque.max_size()= " << c.max_size() << endl;	//1073741821	string target = get_a_target_string();	timeStart = clock();			
auto pItem = find(c.begin(), c.end(), target);	cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;	if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	timeStart = clock();		sort(c.begin(), c.end());						cout << "sort(), milli-seconds : " << (clock()-timeStart) << endl;		c.clear();test_moveable(deque<MyString>(),deque<MyStrNoMove>(), value);		 						
}															
}

使用容器stack

stack本身使用deque实现, stack是先进后出

#include <stack>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj17
{
void test_stack(long& value)
{cout << "\ntest_stack().......... \n";stack<string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.push(string(buf));    			 		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;	cout << "stack.size()= " << c.size() << endl;cout << "stack.top()= " << c.top() << endl;	c.pop();cout << "stack.size()= " << c.size() << endl;cout << "stack.top()= " << c.top() << endl;	{
stack<string, list<string>> c;		//以 list 為底層 for(long i=0; i< 10; ++i) {snprintf(buf, 10, "%d", rand());c.push(string(buf));    			 		}cout << "stack.size()= " << c.size() << endl;cout << "stack.top()= " << c.top() << endl;	c.pop();cout << "stack.size()= " << c.size() << endl;cout << "stack.top()= " << c.top() << endl;	}	{
stack<string, vector<string>> c;	//以 vector 為底層 for(long i=0; i< 10; ++i) {snprintf(buf, 10, "%d", rand());c.push(string(buf));    			 		}cout << "stack.size()= " << c.size() << endl;cout << "stack.top()= " << c.top() << endl;	c.pop();cout << "stack.size()= " << c.size() << endl;cout << "stack.top()= " << c.top() << endl;	}{
stack<string, set<string>> c;	//以 set 為底層 
/*!for(long i=0; i< 10; ++i) {snprintf(buf, 10, "%d", rand());c.push(string(buf));    			 		}cout << "stack.size()= " << c.size() << endl;cout << "stack.top()= " << c.top() << endl;	c.pop();cout << "stack.size()= " << c.size() << endl;cout << "stack.top()= " << c.top() << endl;	//[Error] 'class std::set<std::basic_string<char> >' has no member named 'push_back'
//[Error] 'class std::set<std::basic_string<char> >' has no member named 'back'
//[Error] 'class std::set<std::basic_string<char> >' has no member named 'pop_back'
*/}//!stack<string, map(string>> c5;	以 map 為底層, [Error] template argument 2 is invalid
//!stack<string>::iterator ite1;  	//[Error] 'iterator' is not a member of 'std::stack<std::basic_string<char> >'}															
}

使用容器queue

queue(队列)本身使用deque实现,queue先进先出

#include <queue>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj18
{
void test_queue(long& value)
{cout << "\ntest_queue().......... \n";queue<string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.push(string(buf));    			 		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;	cout << "queue.size()= " << c.size() << endl;cout << "queue.front()= " << c.front() << endl;	cout << "queue.back()= " << c.back() << endl;		c.pop();cout << "queue.size()= " << c.size() << endl;cout << "queue.front()= " << c.front() << endl;	cout << "queue.back()= " << c.back() << endl;	{
queue<string, list<string>> c;		//以 list 為底層 for(long i=0; i< 10; ++i) {snprintf(buf, 10, "%d", rand());c.push(string(buf));    			 		}cout << "queue.size()= " << c.size() << endl;cout << "queue.front()= " << c.front() << endl;	cout << "queue.back()= " << c.back() << endl;		c.pop();cout << "queue.size()= " << c.size() << endl;cout << "queue.front()= " << c.front() << endl;	cout << "queue.back()= " << c.back() << endl;	}	{
queue<string, vector<string>> c;	//以 vector 為底層 for(long i=0; i< 10; ++i) {snprintf(buf, 10, "%d", rand());c.push(string(buf));    			 		}cout << "queue.size()= " << c.size() << endl;cout << "queue.front()= " << c.front() << endl;	cout << "queue.back()= " << c.back() << endl;		//!c.pop();  //[Error] 'class std::vector<std::basic_string<char> >' has no member named 'pop_front'cout << "queue.size()= " << c.size() << endl;cout << "queue.front()= " << c.front() << endl;	cout << "queue.back()= " << c.back() << endl;	}	{
queue<string, set<string>> c;		//以 set 為底層 
/*!for(long i=0; i< 10; ++i) {snprintf(buf, 10, "%d", rand());c.push(string(buf));    			 		}cout << "queue.size()= " << c.size() << endl;cout << "queue.front()= " << c.front() << endl;	cout << "queue.back()= " << c.back() << endl;		c.pop();cout << "queue.size()= " << c.size() << endl;cout << "queue.front()= " << c.front() << endl;	cout << "queue.back()= " << c.back() << endl;
//[Error] 'class std::set<std::basic_string<char> >' has no member named 'push_back'
//[Error] 'class std::set<std::basic_string<char> >' has no member named 'front'
//[Error] 'class std::set<std::basic_string<char> >' has no member named 'pop_front'
*/		}//! queue<string, map<string>> c5;	//以 map 為底層, [Error] template argument 2 is invalid
//! queue<string>::iterator ite1;  	//[Error] 'iterator' is not a member of 'std::queue<std::basic_string<char> >'	
}															
}

6 容器之分类与各种测试(四):set和unordered_set等

使用容器multiset

Set和multiset会根据特定的排序准则,自动将元素排序。两者不同之处在于multiset允许元素重复而set不允许。

#include <set>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj06
{
void test_multiset(long& value)
{cout << "\ntest_multiset().......... \n";multiset<string> c;  	
char buf[10];		
clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.insert(string(buf));     				}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;	cout << "multiset.size()= " << c.size() << endl;	cout << "multiset.max_size()= " << c.max_size() << endl;	//214748364string target = get_a_target_string();	{timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);	//比 c.find(...) 慢很多	cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;		if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	}{timeStart = clock();		
auto pItem = c.find(target);		//比 std::find(...) 快很多							cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;		 if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	}	c.clear();test_moveable(multiset<MyString>(),multiset<MyStrNoMove>(), value);	 						
}															 
}

使用容器multimap

Map和multimap将key/value pair当作元素进行管理。它们可根据key的排序准则自动为元素排序。Multimap允许重复元素,map不允许

#include <map>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj07
{
void test_multimap(long& value)
{cout << "\ntest_multimap().......... \n";multimap<long, string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());//multimap 不可使用 [] 做 insertion c.insert(pair<long,string>(i,buf));   						}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;	cout << "multimap.size()= " << c.size() << endl;cout << "multimap.max_size()= " << c.max_size() << endl;	//178956970	long target = get_a_target_long();		timeStart = clock();		
auto pItem = c.find(target);								cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;	 if (pItem != c.end())cout << "found, value=" << (*pItem).second << endl;elsecout << "not found! " << endl;	  c.clear();		  					
}															 
}

使用容器unordered_multiset

不是基于红黑树,而是基于hash table。允许重复的key存在

#include <unordered_set>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj08
{
void test_unordered_multiset(long& value)
{cout << "\ntest_unordered_multiset().......... \n";unordered_multiset<string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.insert(string(buf));   			  		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;		cout << "unordered_multiset.size()= " << c.size() << endl;cout << "unordered_multiset.max_size()= " << c.max_size() << endl;	//357913941cout << "unordered_multiset.bucket_count()= " << c.bucket_count() << endl;	// 桶的数量cout << "unordered_multiset.load_factor()= " << c.load_factor() << endl;	cout << "unordered_multiset.max_load_factor()= " << c.max_load_factor() << endl;	cout << "unordered_multiset.max_bucket_count()= " << c.max_bucket_count() << endl;				for (unsigned i=0; i< 20; ++i) {cout << "bucket #" << i << " has " << c.bucket_size(i) << " elements.\n";}					string target = get_a_target_string();	{timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);	//比 c.find(...) 慢很多	cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;	if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	}{timeStart = clock();		
auto pItem = c.find(target);		//比 std::find(...) 快很多							cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;	 if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	}		c.clear();test_moveable(unordered_multiset<MyString>(),unordered_multiset<MyStrNoMove>(), value);		 	 							
}													 

使用容器unordered_multimap

允许重复的key存在

#include <unordered_map>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj09
{
void test_unordered_multimap(long& value)
{cout << "\ntest_unordered_multimap().......... \n";unordered_multimap<long, string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());//multimap 不可使用 [] 進行 insertion c.insert(pair<long,string>(i,buf));}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;		cout << "unordered_multimap.size()= " << c.size() << endl;	cout << "unordered_multimap.max_size()= " << c.max_size() << endl;	//357913941	long target = get_a_target_long();		timeStart = clock();		
auto pItem = c.find(target);								cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;		 if (pItem != c.end())cout << "found, value=" << (*pItem).second << endl;elsecout << "not found! " << endl;		
}															 
}

使用容器set

set中key不可重复

#include <set>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj13
{
void test_set(long& value)
{cout << "\ntest_set().......... \n";set<string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.insert(string(buf));     					}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;		cout << "set.size()= " << c.size() << endl;cout << "set.max_size()= " << c.max_size() << endl;	   //214748364string target = get_a_target_string();	{timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);	//比 c.find(...) 慢很多	cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;		if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	}{timeStart = clock();		
auto pItem = c.find(target);		//比 std::find(...) 快很多							cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;		 if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	}							
}															 
}

使用容器map

底部是红黑树,存的元素是不能重复的

#include <map>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj14
{
void test_map(long& value)
{cout << "\ntest_map().......... \n";map<long, string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c[i] = string(buf);  					}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;	cout << "map.size()= " << c.size() << endl;	cout << "map.max_size()= " << c.max_size() << endl;		//178956970long target = get_a_target_long();		timeStart = clock();		
auto pItem = c.find(target);								cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;		 if (pItem != c.end())cout << "found, value=" << (*pItem).second << endl;elsecout << "not found! " << endl;			c.clear();					
}															 
}

使用容器 unordered_set

底层实现是hash table.

#include <unordered_set>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj15
{
void test_unordered_set(long& value)
{cout << "\ntest_unordered_set().......... \n";unordered_set<string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c.insert(string(buf));    			 		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;		cout << "unordered_set.size()= " << c.size() << endl;	cout << "unordered_set.max_size()= " << c.max_size() << endl;  //357913941cout << "unordered_set.bucket_count()= " << c.bucket_count() << endl;	cout << "unordered_set.load_factor()= " << c.load_factor() << endl;	cout << "unordered_set.max_load_factor()= " << c.max_load_factor() << endl;	cout << "unordered_set.max_bucket_count()= " << c.max_bucket_count() << endl;			for (unsigned i=0; i< 20; ++i) {cout << "bucket #" << i << " has " << c.bucket_size(i) << " elements.\n";}			string target = get_a_target_string();	{timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);	//比 c.find(...) 慢很多	cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;		if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	}{timeStart = clock();		
auto pItem = c.find(target);		//比 std::find(...) 快很多							cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;		 if (pItem != c.end())cout << "found, " << *pItem << endl;elsecout << "not found! " << endl;	}	
}															 
}

使用容器unordered_map

底层实现是hash table。

#include <unordered_map>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#include <ctime> 
namespace jj16
{
void test_unordered_map(long& value)
{cout << "\ntest_unordered_map().......... \n";unordered_map<long, string> c;  	
char buf[10];clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", rand());c[i] = string(buf);  		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "milli-seconds : " << (clock()-timeStart) << endl;		cout << "unordered_map.size()= " << c.size() << endl;	//357913941cout << "unordered_map.max_size()= " << c.max_size() << endl;	long target = get_a_target_long();		timeStart = clock();	
//! auto pItem = find(c.begin(), c.end(), target);	//map 不適用 std::find() 			
auto pItem = c.find(target);cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;		 if (pItem != c.end())cout << "found, value=" << (*pItem).second << endl;elsecout << "not found! " << endl;		
}															 
}

7 分配器之测试

使用容器的时候,如果没有显式指定分配器,会使用默认的分配器。

在这里插入图片描述

#include <list>
#include <stdexcept>
#include <string>
#include <cstdlib> 		//abort()
#include <cstdio>  		//snprintf()
#include <algorithm> 	//find()
#include <iostream>
#include <ctime> #include <cstddef>
#include <memory>	//內含 std::allocator  //欲使用 std::allocator 以外的 allocator, 得自行 #include <ext\...> 
#ifdef __GNUC__		
#include <ext\array_allocator.h>
#include <ext\mt_allocator.h>
#include <ext\debug_allocator.h>
#include <ext\pool_allocator.h>
#include <ext\bitmap_allocator.h>
#include <ext\malloc_allocator.h>
#include <ext\new_allocator.h>  
#endifnamespace jj20
{
//pass A object to function template impl(),
//而 A 本身是個 class template, 帶有 type parameter T,  
//那麼有無可能在 impl() 中抓出 T, 創建一個 list<T, A<T>> object? 
//以下先暫時迴避上述疑問.void test_list_with_special_allocator()
{
#ifdef __GNUC__	cout << "\ntest_list_with_special_allocator().......... \n";//不能在 switch case 中宣告,只好下面這樣. 				//1000000次 list<string, allocator<string>> c1;						//3140list<string, __gnu_cxx::malloc_allocator<string>> c2;  	//3110list<string, __gnu_cxx::new_allocator<string>> c3; 		//3156list<string, __gnu_cxx::__pool_alloc<string>> c4;  		//4922list<string, __gnu_cxx::__mt_alloc<string>> c5; 		//3297list<string, __gnu_cxx::bitmap_allocator<string>> c6;  	//4781 														int choice;
long value;     cout << "select: "<< " (1) std::allocator "<< " (2) malloc_allocator "<< " (3) new_allocator "<< " (4) __pool_alloc "<< " (5) __mt_alloc "<< " (6) bitmap_allocator ";cin >> choice;if ( choice != 0 ) {cout << "how many elements: ";cin >> value; 		}char buf[10];			
clock_t timeStart = clock();								for(long i=0; i< value; ++i){try {snprintf(buf, 10, "%d", i);switch (choice) {case 1 : 	c1.push_back(string(buf)); 	break;case 2 : 	c2.push_back(string(buf)); 	break;		case 3 : 	c3.push_back(string(buf)); break;		case 4 : 	c4.push_back(string(buf)); 	break;		case 5 : 	c5.push_back(string(buf)); 		break;		case 6 : 	c6.push_back(string(buf)); 	break;				default: break;		}    		   		}catch(exception& p) {cout << "i=" << i << " " << p.what() << endl;	abort();}}cout << "a lot of push_back(), milli-seconds : " << (clock()-timeStart) << endl;	//test all allocators' allocate() & deallocate();int* p; 	allocator<int> alloc1;	p = alloc1.allocate(1);  alloc1.deallocate(p,1); 	__gnu_cxx::malloc_allocator<int> alloc2;  p = alloc2.allocate(1);  alloc2.deallocate(p,1);  	__gnu_cxx::new_allocator<int> alloc3; 	p = alloc3.allocate(1);  alloc3.deallocate(p,1); 	__gnu_cxx::__pool_alloc<int> alloc4;  	p = alloc4.allocate(2);  alloc4.deallocate(p,2); 	//我刻意令參數為 2, 但這有何意義!! 一次要 2 個 ints? __gnu_cxx::__mt_alloc<int> alloc5; 	p = alloc5.allocate(1);  alloc5.deallocate(p,1);  	__gnu_cxx::bitmap_allocator<int> alloc6;  	p = alloc6.allocate(3);  alloc6.deallocate(p,3);  	//我刻意令參數為 3, 但這有何意義!! 一次要 3 個 ints? 
#endif 			
}															
}

后记

这是STL标准库与泛型编程(侯捷)的第一份笔记,后续笔记会陆续更新。

这篇关于STL标准库与泛型编程(侯捷)笔记1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/582807

相关文章

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念