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标准库与泛型编程(侯捷)的第一份笔记,后续笔记会陆续更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/603789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java流程控制的陷阱

文章目录 1. switch中break的作用2. switch支持的数据类型3. else隐含的条件4. 省略花括号的陷阱5. for循环的结构6. 使用标签跳出双层for循环 流程控制三种&#xff1a;顺序结构、分支结构、循环结构 分支机构两种&#xff1a;if语句、switch语句 循环结构&#xff1a;while循…

JumpServer一键安装脚本

JumpServer 一键安装命令如下&#xff1a; curl -sSL https://resource.fit2cloud.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash上述quick_start.sh脚本详细内容如下&#xff1a; #!/usr/bin/env bash #VERSIONv3.10.1 DOWNLOAD_URLhttps://re…

【APACHE】的认识和基础配置参数

#主页传送:江南的江 #每日鸡汤&#xff1a;人生没有如果和假设&#xff0c;只有后果和结果。生活有进有退&#xff0c;输什么也不能输心情。生活简单就是迷人的&#xff0c;学会简单其实就是不简单。要学会平静地接受现实&#xff0c;学会对自己说声顺其自然&#xff0c;学会坦…

MS4553S用于开漏模式和推拉模式的 2bit 双向电平转换器,可替代TXS0102/PCA9306等

产品简述 MS4553S 是一款双向电平转换器&#xff0c;可以用作混合电压的数字信 号系统中。其使用两个独立构架的电源供电&#xff0c; A 端供电电压范围是 1.65V 到 5.5V &#xff0c; B 端供电电压范围是 2.3V 到 5.5V 。可用在电压为 1.8V 、 2.5V 、 3.3V 和 5V 的信号转…

C++系列十四:结构体

C中的结构体 一、结构体的定义 在C中&#xff0c;结构体是一种自定义的数据类型&#xff0c;它允许我们将不同类型的数据组合在一起。结构体可以包含任意类型的数据&#xff0c;包括基本数据类型、指针、数组、其他结构体等。 定义结构体的语法如下&#xff1a; struct 结构…

目前最完整的WebRTC资源平台 —— 筑梦之路

webrtcwork.com 是一个非常好的网站&#xff0c;笔者从那里获得了很多有价值的学习资源&#xff0c;比如服务器端压力测试&#xff0c;商业WebRTC部署等资料。 地址&#xff1a;webrtcwork - Resources for those working with WebRTC 做个笔记

如何用UE5 的小白人替换成自己的 metahumen 数字人

1、用QuixelBridge 插件导入制作好的metahumen数字人 2、创建项目时如有选择第三人称游戏&#xff0c;在内容目录中找到第三人称游戏小白人的蓝图类&#xff0c;对其进行复制一个&#xff0c;重命名&#xff0c;我这里命名为BP_METAHUMEN&#xff0c; 并移到Metahumen目录下方便…

安全基础~信息搜集3

文章目录 知识补充APP信息搜集php开发学习理解漏洞 知识补充 端口渗透总结 python Crypto报错&#xff1a;https://blog.csdn.net/five3/article/details/86160683 APP信息搜集 1. AppInfoScanner 移动端(Android、iOS、WEB、H5、静态网站)信息收集扫描工具 使用教程 演示&…

第三十八周周报:文献阅读 +BILSTM+GRU+Seq2seq

目录 摘要 Abstract 文献阅读&#xff1a;耦合时间和非时间序列模型模拟城市洪涝区洪水深度 现有问题 提出方法 创新点 XGBoost和LSTM耦合模型 XGBoost算法 ​编辑 LSTM&#xff08;长短期记忆网络&#xff09; 耦合模型 研究实验 数据集 评估指标 研究目的 洪…

适合前后端开发的可视化编辑器(拖拽控件)

分享一个面向研发人群使用的前后端分离的低代码软件——JNPF。 JNPF与市面上其他的低代码&#xff08;轻流、宜搭、微搭、简道云、轻流、活字格等等&#xff09;&#xff0c;后者更倾向于非编程人员使用&#xff0c;让业务线人员自行构建应用程序。而 JNPF 这款低代码产品是面向…

Linux学习记录——삼십유 传输层TCP协议(1)

文章目录 1、TCP协议报文1、报头和有效载荷的分离2、TCP可靠性3、序号和确认序号4、16位窗口大小5、6个标志位和紧急指针 2、TCP可靠性1、应答机制2、超时重传机制3、连接管理机制握手挥手 3、流量控制 1、TCP协议报文 UDP属于TCP/IP协议族。 1、报头和有效载荷的分离 从头…

1、Excel工作场景和知识点总结

参考&#xff1a; 戴师兄–戴你玩转数据分析 Excel发挥战斗力的场景 地量级数据的存储 我们日常所用的各种数据表格&#xff0c;基本都以excel的.xlsx或者.xls格式进行存储。并且因为大家电脑上都有excel&#xff0c;这就使excel的通用性很高(我用excel做好一个表发给你&#x…

uniapp选择android非图片文件的方案踩坑记录

这个简单的问题我遇到下面6大坑&#xff0c;原始需求是选择app如android的excel然后读取到页面并上传表格数据json 先看看效果 uniapp 选择app excel文件读取 1.uniapp自带不支持 uniapp选择图片和视频非常方便自带已经支持可以直接上传和读取 但是选择word excel的时候就出现…

设计模式篇章(3)——七种结构型模式

结构型设计模式主要思考的是如何将对象进行合理的布局来组成一个更大的功能体或者结构体&#xff0c;这个现在讲有点抽象&#xff0c;用大白话讲就是利用现有的对象进行组合或者配合&#xff0c;使得组合后的这个系统更加好。好是相对于不使用设计模式&#xff0c;按照自己的堆…

【小沐学CAD】开源Assimp库导入三维模型(C++、Python)

文章目录 1、简介2、下载编译3、代码测试3.1 C3.2 pyassimp&#xff08;Python&#xff09; 结语 1、简介 https://github.com/assimp/assimp Open Asset Import Library 是一个库&#xff0c;用于将各种 3D 文件格式加载为共享的内存格式。它支持 40 多种用于导入的文件格式和…

API集群负载统计 - 华为OD统一考试

OD统一考试 分值: 100分 题解: Java / Python / C++ 题目描述 某个产品的RESTful API集合部署在服务器集群的多个节点上,近期对客户端访问日志进行了采集,需要统计各个API的访问频次,根据热点信息在服务器节点之间做负载均衡,现在需要实现热点信息统计查询功能。 RESTf…

自定义View之重写onMeasure

一、重写onMeasure()来修改已有的View的尺寸 步骤&#xff1a; 重写 onMeasure()&#xff0c;并调用 super.onMeasure() 触发原先的测量用 getMeasuredWidth() 和 getMeasuredHeight() 取到之前测得的尺寸&#xff0c;利用这两个尺寸来计算出最终尺寸使用 setMeasuredDimensio…

鱼类识别Python+深度学习人工智能+TensorFlow+卷积神经网络算法

一、介绍 鱼类识别系统。使用Python作为主要编程语言开发&#xff0c;通过收集常见的30种鱼类&#xff08;‘墨鱼’, ‘多宝鱼’, ‘带鱼’, ‘石斑鱼’, ‘秋刀鱼’, ‘章鱼’, ‘红鱼’, ‘罗非鱼’, ‘胖头鱼’, ‘草鱼’, ‘银鱼’, ‘青鱼’, ‘马头鱼’, ‘鱿鱼’, ‘鲇…

基于JAVA的中小学教师课程排课系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 角色管理模块2.2 课程档案模块2.3 排课位置模块2.4 排课申请模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 课程表3.2.3 排课位置表3.2.4 排课申请表 四、系统展示五、核心代码5.1 查询课程5.2 新增课…

CentOS-7安装Docker

0.安装Docker Docker 分为 CE 和 EE 两大版本。CE 即社区版&#xff08;免费&#xff0c;支持周期 7 个月&#xff09;&#xff0c;EE 即企业版&#xff0c;强调安全&#xff0c;付费使用&#xff0c;支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道…