1.STL六大部件
- 容器 Containers
- 分配器 Allocators:帮容器分配内存
- 算法 Algorithms
- 迭代器 Iterators:算法通过迭代器操作容器里的数据,是一种泛化的指针
- 适配器 Adapters:修改或扩展已有类或函数的接口以满足特定的需求
- 仿函数 Functors
int main()
{
    int ia[6] = {27, 210, 12, 47, 109, 83};
    vector<int, allocator<int>> vi(ia, ia+6);
    cout << count_if(vi.begin(), vi.end(), not1(bind2nb(less<int>(), 40)));
    system("pause");
    return 0;
}
vector 容器 allocator 分配器 count_if 算法
vi.begin() 迭代器 not1 适配器 less<int>() 仿函数
2.容器的内存分配
三种形式:Sequence Containers, Associative Containers, Unordered Containers

set和map的底层原理都是红黑树
3.auto 关键字
 
auto 关键字用于自动类型推导,让编译器基于初始化表达式来推断变量的类型。这样的语法可以使代码更简洁,减少在声明变量时需要显式指定类型的需求。
在代码 auto pItem = find(c.begin(), c.end(), target); 中:
- find是一个算法,通常在- <algorithm>头文件中定义。它用于在给定的迭代器范围(这里是从- c.begin()到- c.end())内查找与- target相等的第一个元素。
- c是一个容器,如- vector,- list或其他可迭代的容器。
- target是要在容器- c中查找的元素。
auto pItem 表示让编译器自动推导 pItem 的类型。在这种情况下,find 函数返回的是一个迭代器,指向找到的元素。如果没有找到匹配的元素,它将返回 c.end(),表示范围的末尾。
因此,使用 auto 可以避免显式写出复杂的迭代器类型,使代码更易读和易维护。
4. snprintf
snprintf(buf, 10, "%d", rand());  // 将 rand() 函数生成的随机整数格式化为字符串
5.使用容器forward_list
forward_list<string> c;  
snprintf(buf, 10, "%d", rand());
c.push_front(string(buf));  // 头插
6.stack和vector的区别
- vector是一个动态数组。允许随机访问,即可以直接通过索引访问任何元素。支持对容器中元素的前向和后向遍历。
- stack是一种先进后出的数据结构,只能在一端(栈顶)进行添加或删除操作。不支持随机访问,即不能直接访问栈内部的元素,只能访问栈顶元素。
7.multiset/multimap
 
 
- 安插元素用insert
- 使用c.find<>比::find<>快
- 可以放重复值
8.使用容器vector的操作
namespace test_vector
{
    string get_target_string()
    {
        long target = 0;
        char buf[10];
        cout << "target:" << endl;
        cin >> target;
        snprintf(buf, 10, "%ld", target);
        return string(buf);
    }
    void test_vector(long &value)
    {
        vector<string> v;
        char buf[10];
        clock_t timeStart = clock();
        for(long i=0; i<value; i++)
        {
            try{
                snprintf(buf, 10, "%d", rand());
                v.push_back(buf);
            }
            catch(exception& p){
                cout << "i=" << i << " " << p.what() << endl;
                abort();
            }
        }
        cout << "milli-seconds:" << (clock() - timeStart) << endl;
        cout << "vector.max_size()= " << v.max_size() << endl;	//1073747823
        cout << "vector.size()= " << v.size() << endl;		
        cout << "vector.front()= " << v.front() << endl;	
        cout << "vector.back()= " << v.back() << endl;	
        cout << "vector.data()= " << v.data() << endl;
        cout << "vector.capacity()= " << v.capacity() << endl << endl;
        string target = get_target_string();
        {
            timeStart = clock();
            auto p = find(v.begin(), v.end(), target);
            cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
            if(p != v.end())
            {
                cout << "found, " << *p << endl;
            }
            else
            {
                cout << "not found! " << endl;
            }
        }
        {
            timeStart = clock();
            sort(v.begin(), v.end());
            cout << "sort(), milli-seconds : " << (clock()-timeStart) << endl;
            
            timeStart = clock();
            auto p = lower_bound(v.begin(), v.end(), target);
            cout << "lower_bound(), milli-seconds : " << (clock()-timeStart) << endl;
            if (p != v.end())
                cout << "found, " << *p << endl << endl;
            else
                cout << "not found! " << endl << endl;	
        }
        v.clear();
    }
}
9.常见的容器定义
// 单端数组
#include<vector>
vector<string> v;
// 双端队列
#include <deque>
deque<string> c;
// 链表
#include <list>
#include <forward_list>
list<string> c;
forward_list<string> c;
// 红黑树
#include <set>
#include <map>
set<string> v;
multiset<string> c;  // 插入元素用c.insert(string(buf))
map<int, string> c;
multimap<int, string> c;  // c.insert(pair<int, string>(i,buf))
// 哈希表
#include <unordered_set>
unordered_set<string> c;
unordered_multiset<string> c;  	
#include <unordered_map>
unordered_map<long, string> c;  
unordered_multimap<long, string> c;
// 栈
#include <stack>
stack<string> c;  // 默认以deque为底层
stack<string, list<string>> c;		//以 list 為底層
stack<string, vector<string>> c;	//以 vector 為底層
stack<string, set<string>> c;	//以 set 為底層
10.使用分配器allocator
#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>  
namespace test_allocator
{
		void test_allocator(int &value)
		{
		list<string, allocator<string>> c1;						
		list<string, __gnu_cxx::malloc_allocator<string>> c2;  	
    list<string, __gnu_cxx::new_allocator<string>> c3; 		
		list<string, __gnu_cxx::__pool_alloc<string>> c4;  		
		list<string, __gnu_cxx::__mt_alloc<string>> c5; 		
    list<string, __gnu_cxx::bitmap_allocator<string>> c6;
    
    c.push_back(value);
    // 定义指针和分配器
    int* p; 	
		allocator<int> alloc1;
		// 分配内存:1表示要分配的对象数目。函数返回一个指向分配内存的指针。
		p = alloc1.allocate(1);
		// 释放内存
		alloc1.deallocate(p, 1);
		}
		
		// 使用 C 标准库中的 malloc 和 free 进行内存分配和释放
		__gnu_cxx::malloc_allocator<int> alloc2;  
		p = alloc2.allocate(1);  
		alloc2.deallocate(p,1);  	
		
		// 使用 C++ 的 new 和 delete 操作符进行内存分配和释放
	  __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);
		
		// 设计用于多线程环境,可以安全地在多个线程中使用。
		__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);
}



















