全面解析 C++ STL 中的 set 和 map
C++ 标准模板库(STL)中的关联式容器以其强大的功能和高效性成为开发者解决复杂数据组织问题的重要工具。其中,set
和 map
是最常用的两类关联容器。本篇博客将从基本特性、底层实现、用法详解、高级案例以及性能优化等多个角度,详细解读它们的设计与使用。
目录
1. 什么是关联式容器
关联式容器的核心特性
2. set 容器详解
2.1 基本概念与特性
2.2 底层实现:红黑树
红黑树的特性
红黑树的操作
2.3 构造函数
2.4 常用操作与复杂度分析
插入操作
查找操作
删除操作
遍历
2.5 特殊操作与技巧
(1) 自定义排序规则
(2) 范围删除
(3) 应用:求两个数组的交集
2.6 multiset 的区别与应用
1. 什么是关联式容器
关联式容器是一类根据关键字组织和管理数据的容器。与序列式容器(如 vector
和 list
)相比,关联式容器的主要区别如下:
特性 | 关联式容器(set /map ) | 序列式容器(vector /list ) |
---|---|---|
数据存储顺序 | 按关键字排序 | 按插入顺序 |
数据访问复杂度 | O(logN)O(\log N)O(logN) | O(1)O(1)O(1) 或 O(N)O(N)O(N) |
是否支持随机访问 | 否 | 是 |
是否支持按索引访问 | 否 | 是 |
关联式容器分为有序和无序两类:
- 有序容器:如
set
和map
,基于平衡二叉树(红黑树)实现,数据按排序规则组织。 - 无序容器:如
unordered_set
和unordered_map
,基于哈希表实现,提供更高效的查找速度,但不保证元素顺序。
关联式容器的核心特性
- 键值对:关联式容器通过关键字对元素进行组织,
set
中的关键字即为数据本身,而map
则以键值对形式存储数据。 - 自动排序:有序容器会自动对数据进行排序(升序或自定义规则)。
- 高效操作:插入、删除、查找的平均时间复杂度为 O(logN)O(\log N)O(logN)(红黑树实现)。
2. set
容器详解
2.1 基本概念与特性
set
是一种集合数据结构,用于存储唯一且自动排序的元素。它的主要特点如下:
- 数据唯一性:同一元素不能重复插入。
- 自动排序:默认按升序排序,可通过自定义比较器更改排序规则。
- 迭代器类型:
set
支持双向迭代器,不支持随机访问。 - 底层实现:使用红黑树作为存储结构。
2.2 底层实现:红黑树
红黑树的特性
红黑树是一种平衡二叉搜索树,满足以下性质:
- 每个节点是红色或黑色。
- 根节点是黑色。
- 每个叶子节点(
nullptr
或 NIL 节点)是黑色。 - 如果一个节点是红色,则其子节点必须是黑色(即红色节点不能相邻)。
- 从任意节点到其每个叶子节点的路径都包含相同数量的黑色节点。
红黑树的操作
- 插入:通过旋转和重新着色,确保平衡性和红黑性质。
- 删除:比插入更复杂,同样通过旋转和着色维护树的性质。
- 查找:沿树遍历,时间复杂度为 O(logN)O(\log N)O(logN)。
在 set
和 map
中,红黑树用来高效实现元素的有序存储和快速查找。
2.3 构造函数
set
提供以下几种构造方式:
- 默认构造:创建一个空集合。
set<int> s;
- 初始化列表构造:直接用
{}
初始化集合。set<int> s = {3, 1, 4, 1, 5, 9}; // 重复元素自动去重
- 迭代器区间构造:从其他容器的元素构造集合。
vector<int> v = {1, 2, 3, 4}; set<int> s(v.begin(), v.end());
- 自定义比较规则:
set<int, greater<int>> s = {3, 1, 4}; // 按降序排序
2.4 常用操作与复杂度分析
操作 | 函数 | 复杂度 | 说明 |
---|---|---|---|
插入 | insert(value) | O(logN)O(\log N)O(logN) | 插入元素,若已存在则插入失败 |
删除 | erase(value) | O(logN)O(\log N)O(logN) | 删除指定元素 |
查找 | find(value) | O(logN)O(\log N)O(logN) | 返回迭代器,指向目标元素 |
统计 | count(value) | O(logN)O(\log N)O(logN) | 判断元素是否存在,结果为 0 或 1 |
遍历 | begin(), end() | O(N)O(N)O(N) | 正向迭代访问所有元素 |
下界/上界 | lower_bound()/upper_bound() | O(logN)O(\log N)O(logN) | 返回 >= / > 某值的第一个元素的迭代器 |
插入操作
set<int> s;
auto res = s.insert(10); // 插入 10
if (res.second) {cout << "插入成功" << endl;
} else {cout << "插入失败" << endl;
}
查找操作
if (s.find(20) != s.end()) {cout << "找到元素 20" << endl;
}
删除操作
s.erase(10); // 删除值为 10 的元素
遍历
for (int x : s) {cout << x << " "; // 正向遍历
}
for (auto it = s.rbegin(); it != s.rend(); ++it) {cout << *it << " "; // 反向遍历
}
2.5 特殊操作与技巧
(1) 自定义排序规则
set
默认按升序排序,使用仿函数或 std::greater
可修改排序规则:
set<int, greater<int>> s = {3, 1, 4};
(2) 范围删除
删除值在 [low, high)
范围内的所有元素:
s.erase(s.lower_bound(10), s.upper_bound(50));
(3) 应用:求两个数组的交集
vector<int> intersection(const vector<int>& nums1, const vector<int>& nums2) {set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());vector<int> result;for (int x : s1) {if (s2.count(x)) result.push_back(x);}return result;
}
2.6 multiset
的区别与应用
multiset
与 set
的区别在于:
multiset
允许存储重复元素。- 插入、删除和查找操作的接口与
set
相同,但返回的结果会包含重复项。
multiset<int> ms = {1, 2, 2, 3};
ms.insert(2); // 再次插入 2
3. map
容器详解
3.1 基本概念与特性
map
是一个关联式容器,用于存储键值对(key-value
)。与 set
相比,map
不仅存储键(key
),还存储与每个键关联的值(value
)。map
的主要特点包括:
- 键唯一性:每个键在
map
中都是唯一的。 - 自动排序:默认按照键的升序排序,也可以通过自定义比较器来更改排序规则。
- 底层实现:基于红黑树实现,操作复杂度为 O(logN)O(\log N)O(logN)。
- 支持随机访问:与
set
不同,map
中存储的键值对支持通过键快速查找对应的值。
map<int, string> m;
m[1] = "apple"; // 插入键值对 (1, "apple")
m[2] = "banana"; // 插入键值对 (2, "banana")
m[3] = "cherry"; // 插入键值对 (3, "cherry")
内部存储结构
map
使用红黑树存储数据,保证了所有元素按键值自动排序。在 map
中,每个节点存储一个 pair<const Key, T>
,其中 const Key
表示键,T
表示值。红黑树的特点确保了查找、插入和删除操作的时间复杂度都为 O(logN)O(\log N)O(logN)。
3.2 构造与初始化
map
提供了多种构造方法,以适应不同的使用场景:
-
默认构造:创建一个空
map
。map<int, string> m;
-
初始化列表构造:通过初始化列表直接创建
map
。map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
-
范围构造:从另一个容器(如
set
、vector
等)构造map
。vector<pair<int, string>> v = {{1, "apple"}, {2, "banana"}}; map<int, string> m(v.begin(), v.end());
-
自定义比较器:通过传入自定义比较器,指定键的排序方式。
map<int, string, greater<int>> m; // 降序排序 m[2] = "banana"; m[1] = "apple";
3.3 常用操作与复杂度分析
操作 | 函数 | 复杂度 | 说明 |
---|---|---|---|
插入 | insert(pair) | O(logN)O(\log N)O(logN) | 插入一个键值对,若已存在则插入失败 |
插入或修改 | operator[] | O(logN)O(\log N)O(logN) | 插入新元素或修改已有元素的值 |
查找 | find(key) | O(logN)O(\log N)O(logN) | 查找指定键,返回键值对的迭代器 |
统计 | count(key) | O(logN)O(\log N)O(logN) | 查找指定键是否存在(map 中为 0 或 1) |
删除 | erase(key) | O(logN)O(\log N)O(logN) | 删除指定键及其对应的值 |
遍历 | begin(), end() | O(N)O(N)O(N) | 正向遍历所有元素 |
下界/上界 | lower_bound(key) /upper_bound(key) | O(logN)O(\log N)O(logN) | 查找大于等于某值或大于某值的第一个元素 |
插入与查找操作
-
插入:可以通过
insert
方法插入新的键值对,也可以通过operator[]
插入或修改键值对。map<int, string> m; m.insert({1, "apple"}); m[2] = "banana"; // 插入或修改
-
查找:
find
方法返回一个迭代器,指向指定键的键值对,若未找到则返回end()
。auto it = m.find(1); if (it != m.end()) {cout << "Found: " << it->second << endl; // 输出 "apple" }
删除操作
删除某个键值对:
m.erase(1); // 删除键为 1 的元素
3.4 遍历与修改
map
提供了多种遍历方法:
-
范围 for:
for (const auto& [key, value] : m) {cout << key << ": " << value << endl; }
-
传统迭代器:
for (auto it = m.begin(); it != m.end(); ++it) {cout << it->first << ": " << it->second << endl; }
修改值
可以通过迭代器直接修改值,operator[]
也支持修改已有键的值:
m[2] = "grape"; // 修改键为 2 的值为 "grape"
auto it = m.find(2);
if (it != m.end()) {it->second = "orange"; // 通过迭代器修改值
}
3.5 特殊操作与进阶技巧
(1) 下界与上界
通过 lower_bound()
和 upper_bound()
方法,可以获取某个键的下界和上界,常用于区间查找。
lower_bound(key)
:返回第一个大于等于key
的元素。upper_bound(key)
:返回第一个大于key
的元素。
map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
auto lb = m.lower_bound(2); // 返回键为 2 或大于 2 的第一个元素
cout << lb->second << endl; // 输出 "banana"
(2) 自定义排序规则
如同 set
,map
也可以通过自定义比较器来实现不同的排序规则。
map<int, string, greater<int>> m = {{1, "apple"}, {3, "cherry"}, {2, "banana"}};
for (const auto& [key, value] : m) {cout << key << ": " << value << endl;
} // 输出:3: cherry 2: banana 1: apple
(3) 范围删除
删除某个键值范围内的元素,常用于清除一段区间:
map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
m.erase(m.lower_bound(2), m.upper_bound(3)); // 删除键为 2 和 3 的元素
3.6 multimap
的区别与应用
multimap
是 map
的扩展,允许相同的键有多个值(即支持键的冗余)。与 map
的区别在于,multimap
在插入重复键时不会丢失数据,而 map
会自动覆盖原有键。
multimap<int, string> mm;
mm.insert({1, "apple"});
mm.insert({1, "banana"});
mm.insert({2, "cherry"});for (const auto& [key, value] : mm) {cout << key << ": " << value << endl; // 输出:1: apple 1: banana 2: cherry
}
multimap
在某些场景下非常有用,例如存储学生成绩时,可能有多个学生取得相同的分数。
4. 高级案例:综合利用 set
和 map
4.1 查找两个数组的交集
vector<int> intersection(const vector<int>& nums1, const vector<int>& nums2) {set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());vector<int> result;for (int x : s1) {if (s2.count(x)) result.push_back(x);}return result;
}
4.2 构建词频统计表
map<string, int> wordCount(const vector<string>& words) {map<string, int> wordMap;for (const string& word : words) {wordMap[word]++;}return wordMap;
}
4.3 高效查找链表中的环
bool hasCycle(ListNode* head) {set<ListNode*> visited;while (head != nullptr) {if (visited.find(head) != visited.end()) {return true; // 找到环}visited.insert(head);head = head->next;}return false;
}
5. 性能优化与注意事项
5.1 使用 unordered_map
和 unordered_set
在很多查找密集型的应用中,unordered_map
和 unordered_set
基于哈希表实现,提供常数时间复杂度 O(1)O(1)O(1) 的查找和插入操作。它们的性能优势适用于不需要保持元素顺序的场景。
5.2 避免不必要的拷贝
当插入大量数据时,可以使用 emplace()
来避免不必要的对象拷贝。emplace()
可以直接构造元素,而无需创建临时对象。
map<int, string> m;
m.emplace(1, "apple"); // 不会发生拷贝
5.3 避免频繁修改键
map
不支持修改键,修改键会导致数据结构破坏。因此,避免频繁修改键,而应使用新的键值对进行插入和删除。
6. 总结
通过本文的详细解析,我们全面了解了 C++ 中 set
和 map
容器的使用、底层实现以及高效操作技巧。掌握这些基本知识后,开发者可以灵活使用 set
和 map
来处理各种复杂的关联数据问题,从而提高程序的效率和可读性。
在实际开发中,选择合适的容器(如 map
与 unordered_map
,set
与 unordered_set
)可以帮助我们应对不同的数据处理需求,避免性能瓶颈。希望通过本文的学习,你能够深入掌握这些强大的容器,提升 C++ 编程技能。
相关文章:
全面解析 C++ STL 中的 set 和 map
C 标准模板库(STL)中的关联式容器以其强大的功能和高效性成为开发者解决复杂数据组织问题的重要工具。其中,set 和 map 是最常用的两类关联容器。本篇博客将从基本特性、底层实现、用法详解、高级案例以及性能优化等多个角度,详细…...
css:怎么设置div背景图的透明度为0.6不影响内部元素
目录 1.前言 2.解决思路 3.具体实例 4.另外一种实例 5.总结 1.前言 div背景图为project-bg.png,设置div透明度为0.6;div内的名称、数值受透明度影响颜色显示不正常;怎么设置背景图的透明度为0.6不影响内部元素; 2.解决思路 …...
Kubernetes ConfigMaps
文章目录 简介创建ConfigMaps通过命令行使用字面值创建 ConfigMap。从文件创建ConfigMaps从多个文件创建 ConfigMap从目录创建 ConfigMap使用 YAML 创建 ConfigMap 使用ConfigMaps使用 ConfigMaps作为环境变量使用 ConfigMap 作为卷挂载使用 ConfigMap 中的特定的key ConfigMap…...
前端热门面试题目[一](HTML、CSS、Javascript、Node、Vue、React)
如何设计一个前端页面,实现PC端访问展示Web应用,移动端访问展示H5应用? 为了实现这一功能,通常需要使用响应式设计或者服务器端检测用户设备并返回相应的页面。以下是一些实现方法: 响应式设计:通过CSS媒…...
Swift 宏(Macro)入门趣谈(五)
概述 苹果在去年 WWDC 23 中就为 Swift 语言新增了“其利断金”的重要小伙伴 Swift 宏(Swift Macro)。为此,苹果特地用 2 段视频(入门和进阶)颇为隆重的介绍了它。 那么到底 Swift 宏是什么?有什么用&…...
ES6 Set、Map、WeakSet、WeakMap 四者辨析与实战应用详解
在 ES6 中,Set 和 Map 是两种非常重要的新增数据结构,它们都具有独特的特性和用途,能够帮助开发者更高效地处理和管理数据。除此之外,WeakSet 和 WeakMap 作为这两种数据结构的变种,也具有一些特殊的功能。下面我会从 Set 数据结构、Map 数据结构、WeakSet 和 WeakMap 对比…...
【数据结构】哈希表实现
前言 在本篇博客中,作者将会带领你使用C语言来实现一个哈希表。 一.什么是哈希表 在实现哈希表之前,我们先来学习一下什么是哈希表。 在传统的数据结构中,例如数组,链表和二叉平衡树等数据结构,这些数据结构的元素关键…...
Verilog的线与类型与实例化模块
1、线与类型 在Verilog中,线与(wire-AND)类型通常用于描述多个信号进行逻辑与(AND)操作的电路行为。虽然Verilog本身没有直接定义一种名为“线与”的数据类型,但可以通过使用wire类型结合特定的逻辑操作来…...
芯片测试-RF中的S参数,return loss, VSWR,反射系数,插入损耗,隔离度等
RF中的S参数,return loss, VSWR,反射系数,插入损耗,隔离度 💢S参数💢💢S11与return loss,VSWR,反射系数💢💢S21,插入损耗和增益&#…...
强化学习的几个主要方法(策略梯度、PPO、REINFORCE实现等)(上)
本笔记有大量参考蘑菇书EasyRL https://datawhalechina.github.io/easy-rl/#/ 包括其配图和部分文本。 1. 基本概念 1.1 基本流程 强化学习是一种学习框架,其中智能体(Agent) 通过与 环境(Environment) 的交互&#…...
Git远程仓库操作
文章目录 远程仓库连接Gitee克隆代码 多人协同问题说明 🏡作者主页:点击! 🤖Git专栏:点击! ⏰️创作时间:2024年12月1日13点10分 远程仓库 Git 是分布式版本控制系统,同一个 Git …...
GAGAvatar: Generalizable and Animatable Gaussian Head Avatar 学习笔记
1 Overall GAGAvatar(Generalizable and Animatable Gaussian Avatar),一种面向单张图片驱动的可动画化头部头像重建的方法,解决了现有方法在渲染效率和泛化能力上的局限。 旋转参数 现有方法的局限性: 基于NeRF的方…...
什么是VISUAL STUDIO CODE (V S CODE)
Visual Studio Code(简称VS Code)是由微软开发的一个免费的、开源的源代码编辑器。它是一个轻量级但功能强大的工具,支持多种编程语言和框架,广泛用于开发各种应用程序,尤其是Web开发。VS Code具备以下特点:…...
2024年09月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析
青少年软件编程(Python)等级考试试卷(三级) 分数:100 题数:38 一、单选题(共25题,共50分) 1. 以下表达式的值为True的是?( ) A. all( ,1,2,3) B. any([]) C. bool(abc) D. divmod(6,0)...
C++初阶——动态内存管理
目录 1、C/C内存区域划分 2、C动态内存管理:malloc/calloc/realloc/free 3、C动态内存管理:new/delete 3.1 new/delete内置类型 3.2 new/delete自定义类型 4、operator new与operator delete函数 5、new和delete的实现原理 5.1 内置类型 5.2 自定…...
如何查看阿里云ddos供给量
要查看阿里云上的 DDoS 攻击量,你可以通过阿里云的 云盾 DDoS 防护 服务来进行监控和查看攻击数据。阿里云提供了详细的流量监控、攻击日志以及攻击趋势分析工具,帮助用户实时了解 DDoS 攻击的情况。以下是九河云总结的查看 DDoS 攻击量的步骤࿱…...
MySQL中的事务隔离全详解
第一部分:MySQL事务的特性与并行事务引发的问题 1. 什么是事务及其四大特性(ACID)? 事务(Transaction)是数据库操作的基本单位,它将一组操作组合在一起,以确保这些操作作为一个整体…...
异常--C++
文章目录 一、异常的概念及使用1、异常的概念2、异常的抛出和捕获3、栈展开4、查找匹配的处理代码5、异常重新抛出6、异常安全问题7、异常规范 二、标准库的异常 一、异常的概念及使用 1、异常的概念 异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并…...
SeggisV1.0 遥感影像分割软件【源代码】讲解
在此基础上进行二次开发,开发自己的软件,例如:【1】无人机及个人私有影像识别【2】离线使用【3】变化监测模型集成【4】个人私有分割模型集成等等,不管是您用来个人学习还是公司研发需求,都相当合适,包您满…...
锁-读写锁-Swift
实现一 pthread_mutex_t: ReadWriteLock/Sources/ReadWriteLock at main SomeRandomiOSDev/ReadWriteLock GitHub https://swiftpackageindex.com/reers/reerkit/1.0.39/documentation/reerkit/readwritelock/ // // Copyright © 2022 reers. // // Pe…...
Kafka如何保证消息可靠?
大家好,我是锋哥。今天分享关于【Kafka如何保证消息可靠?】面试题。希望对大家有帮助; Kafka如何保证消息可靠? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka通过多种机制来确保消息的可靠性,主要包…...
5.10【机器学习】
如果FLAG的画,就是已经有模型了,不然就新建一个模型,通过TORCH方法 在训练的时候,如果TRAIN的话就是训练,不然就是预测 forward前向预测出来一个结果,就是1234 在train方法里,进行多轮迭代&am…...
[白月黑羽]关于仿写股票数据软件题目的解答
原题: 对应问题视频: 实现的效果 不同点 实现的作品和原题要求的不同点 题目要求爬虫获取数据,作品中是调库获取所有股票历史数据实时数据使用爬虫的方式爬取指定股票的数据,需要实时更新,我做了修改,改…...
详解LZ4文件解压缩问题
详解LZ4文件解压缩问题 一、LZ4文件解压缩方法1. 使用LZ4命令行工具2. 使用Python库3. 使用第三方工具4. 在线解压工具 二、常见问题及解决方法1. 解压显示文件损坏2. 解压后文件大小异常 三、总结 LZ4是一种快速的压缩算法,广泛应用于需要实时压缩和解压缩大文件的…...
vue项目中单独文件的js不存在this.$store?.state怎么办
在Vue项目中,如果你在单独的文件(比如插件、工具函数等)中遇到this.$store不存在的情况,这通常是因为this上下文不指向Vue实例,或者Vuex store没有被正确地注入到Vue实例中。以下是几种可能的解决方案: 确保…...
Github提交Pull Request教程 Git基础扫盲(零基础易懂)
1 PR是什么? PR,全称Pull Request(拉取请求),是一种非常重要的协作机制,它是 Git 和 GitHub 等代码托管平台中常见的功能,被广泛用于参与社区贡献,从而促进项目的发展。 PR的整个过…...
Java函数式编程【二】【Stream的装饰】【中间操作】【map映射器】【摊平映射器flatMap】
一、Java的Stream流式编程中的中间操作 Java的Stream流式编程中,中间操作是对数据流进行处理的一种方式,这些操作通常返回流对象本身,以便可以链接更多的操作。以下是一些常见的中间操作: filter(Predicate predicate) - 用于通过…...
树莓派明明安装了opencv和numpy,却找不到
当然不止树莓派,配置python环境都可能存在这个问题 可能是因为安装的 numpy 或者 opencv 版本与 Python 的包路径不匹配。下面是问题的常见原因及解决方法:【方法一和二优先考虑】 原因分析 多版本 Python 环境冲突: 树莓派上可能有多个版本…...
numpy.float8不存在;Python中,实现16位浮点数
目录 python中矩阵的浮点数存储 numpy.float8不存在 Python中,实现16位浮点数 实现 float16 关于 float8 python中矩阵的浮点数存储 在Python中,矩阵通常是通过嵌套列表(list of lists)、NumPy数组(numpy.ndarray)或其他类似的数据结构来表示的。矩阵中存储的数值所…...
Redis集群配置 (不使用docker 部署)
1. Redis集群简介 1.1 什么是Redis集群 Redis集群是一种通过将多个Redis节点连接在一起以实现高可用性、数据分片和负载均衡的技术。它允许Redis在不同节点上同时提供服务,提高整体性能和可靠性。根据搭建的方式和集群的特性,Redis集群主要有三种模式&…...
做网站用的主机多少合适/人力资源管理师
题意 求 \([L, R]\) 之间的素数之和 . \(L≤10^{10},210^{10} \le R \le 10^{11}\) 题解 一个有点裸的 min_25筛 ? 现在我只会筛素数的前缀和 , 合数的过几天再学吧 . 首先推荐一波 yyb大佬博客 这个人很强 , 别那么fake就好啦 令 \(F(x) x\) 显然此处 \(F(x)\) 是完全积性函…...
企业做网站哪家便宜/成都网络营销搜索推广
LINQ LINQ,语言集成查询(Language INtegrated Query)是一组用于C#和Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。 基本概念可以参考: http://baike.baidu.com/view/965131.htm…...
外包网站建设/seo+网站排名
## 元类:python 元类:用来创建类的类。类对象都是有type实例化产生的。 类也是对象,可以把一个类当作普通对象用来使用,必须存储到列表中,或者作为参数传给函数等等... 元类都继承type 一个类对象由三部分组成: 1&…...
包头怎样做网站/sem是什么基团
从小就喜欢那些穿制服的人,小的时候觉得那些穿制服的叔叔阿姨很威风。长大了后,尤其是在警服从以前的绿色改成黑色后,就越发的喜欢了,黑色的警服外加白闪闪的警徽,简直酷到不行!舅妈就是一个人民警察&#…...
顺德大良营销网站建设/全球搜钻
PHP中的多维数组是指包含一个或多个数组的数组。在多维数组中主数组中的每一个元素也可以是一个数组,子数组中的每一个元素也可以是一个数组,并且一个数组中的值可以是另一个数组,另一个数组的值也可以是一个数组。PHP多维数组是指什么&#…...
零代码建站/网络安全培训机构排名
http://react-native.cn/docs/getting-started.html...