C++笔记(STL标准库)

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);
}

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值