#include "STLUse.h" #include #include #include #include #include #include void show_demo() { stack_demo(); adapter_demo(); search_demo(); } // 概述 void summarize() { // 1.STL: 容器、算法、迭代器、仿函数、适配器、空间配置器。 // 2.容器 // (1)顺序容器: vector[动态数组]、deque[双向队列]、list[双向链表] // (2)关联容器:set/multiset[集合]、map/multimap[字典] // (3)容器适配器<从deque封装>:stack[栈]、queue[队列]、priority_queue[优先级队列] // 3.各容器简介 // (1)vector: 内存连续。 // (2)deque: 内存连续,在两端增删具有较佳的性能。 // (3)list: 内存不连续,不随机存取。 // (4)集合带 multi 的,允许 key 重复。 // 4.map hashtable deque list实现原理 // (1)map: 内部是红黑树实现,可以自动排序,因此内部元素是有序的。 // (2)hashtable: 函数映射的思想记录存储位置和关键字。 // (3)deque: 内部实现是双向队列。 // (4)list: 内部实现是双向链表。 // 5.容器操作复杂度 // (1)vector,插入[O(N)]、查看[O(1)]、删除[O(N)]。 // (2)deque,插入[O(N)]、查看[O(1)]、删除[O(N)]。 // (3)list,插入[O(1)]、查看[O(N)]、删除[O(1)]。 // (4)map、set、multiset、multimap<红黑树,平衡二叉树>,插入[O(logN)]、查看[O(logN)]、删除[O(logN)]。 // (5)unordered_map、unordered_set、unordered_multimap、 // unordered_multiset: // 插入:O(1),最坏O(N) // 查看:O(1),最坏O(N) // 删除:O(1),最坏O(N) // x.空间适配器 } void stack_demo() { std::stack stack{}; // 不提供遍历行为 SimuData da{}; da.data_ = 89; da.value_ = 5.2; stack.push(da); while (!stack.empty()) { std::cout << stack.top().data_ << std::endl; stack.pop(); // 出栈 } } void queue_demo() // 队列 { // 无迭代器 } void list_demo() { // 双向循环链表 // 性质:插入删除操作不会造成原有的迭代器实现,vector 不行。 } void set_demo() { // 特性:key 会被自动排序,不允许有重复的值。 // set 的 iterator 是一种 const_iterator,因为 set的元素值就是 // 键值,关系到 set 元素的排序规则。 } void multi_set_demo() { // 与 set 特性用法一致。差别在于可以key重复。 // 与 set 一样底层实现使用的是红黑树。 } // binary_function 指二元 (这个函数被标记了 弃用) // class A : public std::binary_function // { // public: // void operator()(int val, int start) const // { // std::cout << "val:" << val << " start:" << start // << " total:" << val + start << "\n"; // } // }; // 取反适配器 (unary_function 这个函数被标记了 弃用) // class MGreator : public std::unary_function // { // public: // bool operator()(int val) const // { // // 大于 3 // return val > 3; // } // }; void my_print(int val) { std::cout << val << std::endl; } void my_print2(int val, int start) { std::cout << val << " " << start << std::endl; } class Person { public: Person(std::string name, int age) { name_ = name; age_ = age; } void print() { std::cout << age_ << " "; std::cout << name_ << "\n"; } std::string name_{}; int age_{}; }; void my_print3(const Person& person) { std::cout << person.age_ << " "; std::cout << person.name_ << "\n"; } // 仿函数的目的:协助算法完成不同的策略。 void adapter_demo() { std::vector vec{}; vec.push_back(1); vec.push_back(2); vec.push_back(3); vec.push_back(4); vec.push_back(5); // bind2nd 将45绑定到第二个参数, bind1st 将45绑定到第一个参数 // 《函数对象适配器》 (bind2nd 这个函数被标记了 弃用) // std::for_each(vec.begin(), vec.end(), std::bind2nd(A(), 45)); // std::vector::iterator iter = // std::find_if(vec.begin(), vec.end(), MGreator()); // if (iter != vec.end()) { // // 找到 *iter // std::cout << *iter << std::endl; // } // (not1 ==> 一元的取反) // iter = std::find_if(vec.begin(), vec.end(), std::not1(MGreator())); // if (iter != vec.end()) { // // 找到 *iter // std::cout << *iter << std::endl; // } // 这是另一个示例 deprecated-declarations (bind2nd 这个函数被标记了 弃用) // iter = std::find_if(vec.begin(), vec.end(), // std::not1(std::bind2nd(std::greater(), 3))); // if (iter != vec.end()) { // // 找到 *iter // std::cout << *iter << std::endl; // } // 《函数适配器》 std::for_each(vec.begin(), vec.end(), my_print); // 将函数指针适配成函数的对象 ptr_fun (bind2nd ptr_fun 这个函数被标记了 弃用) // std::for_each(vec.begin(), vec.end(), // std::bind2nd(std::ptr_fun(my_print2), 1000)); // 《成员函数适配器》 std::vector pvec{}; pvec.emplace_back("A", 1); pvec.emplace_back("B", 2); pvec.emplace_back("C", 3); pvec.emplace_back("D", 4); pvec.emplace_back("E", 5); std::for_each(pvec.begin(), pvec.end(), my_print3); // 利用 mem_fun_ref 适配一下。 (mem_fun_ref 这个函数被标记了 弃用) // std::for_each(pvec.begin(), pvec.end(), std::mem_fun_ref(&Person::print)); } // 常用查找算法 void search_demo() { std::vector demo{}; demo.push_back(23); demo.push_back(21); demo.push_back(87); demo.push_back(11); demo.push_back(11); demo.push_back(6); demo.push_back(90); // find 直接按照值去查找 std::vector::iterator iter = std::find(demo.begin(), demo.end(), 11); if (iter != demo.end()) { std::cout << *iter << std::endl; } // find_if 使用你提供的条件去查找 // 同理 count 和 count_if 也是如此。 // adjacent_find 查找相邻的重复元素 iter = std::adjacent_find(demo.begin(), demo.end()); if (iter != demo.end()) { std::cout << "相邻的重复元素:" << *iter << std::endl; } // binary_search 二分查找法,需要有序。 } void predicate_demo() { // 谓词是指普通函数或重载的operator(返回值是bool类型的函数对象(仿函数) } void traverse_demo() { // 遍历算法 // transform 用于搬运 } // 排序 void sort_demo() { // merge 合并,两个容器需要有序 // sort 排序 // random_shuffle 随机调整次序 // reverse 翻转 } // 集合算法 void set_algorithm_demo() { // set_intersection 求交集 // set_unin 求并集 // set_difference 差集 }