我是靠谱客的博主 含糊烧鹅,这篇文章主要介绍黑马C++ 03 提高6 —— STL常用容器_set/multiset容器/map/multimap容器一、set/multiset容器二、map/multimap容器三、案例——员工分组,现在分享给大家,希望可以做个参考。

文章目录

  • 一、set/multiset容器
    • 1. set基本概念
    • 2. set构造和赋值
    • 3. set大小和交换
    • 4. set插入和删除
    • 5. set查找和统计
    • 6. set与multiset区别
    • 7. pair对组创建
    • 8. set容器排序
      • 8.1 内置类型指定排序
      • 8.2 自定义数据类型指定排序
  • 二、map/multimap容器
    • 1. map基本概念
    • 2. map构造和赋值
    • 3. map大小和交换
    • 4. map插入和删除
    • 5. map查找和统计
    • 6. map排序
  • 三、案例——员工分组
    • 1. 案例描述
    • 2. 实现步骤

一、set/multiset容器

1. set基本概念

简介:

  • 所有元素都会在插入时自动被排序

本质:

  • set/multiset属于关联式容器,底层结构是用二叉树实现。

set和multiset区别

  • set不允许容器中有重复的元素
  • multiset允许容器中有重复的元素

2. set构造和赋值

功能描述:

  • 创建set容器以及赋值

构造:

  • set<T> st; 默认构造函数:
  • set(const set &st); 拷贝构造函数

赋值:

  • set& operator=(const set &st); 重载等号操作符

总结:

  • set容器插入数据时用insert
  • set容器插入数据的数据会自动排序
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<iostream> #include<set> using namespace std; // set容器构造与赋值操作 // 遍历 void printSet(set<int>& s) { for (set<int>::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { set<int>s1; // 插数据只有insert方式 s1.insert(10); s1.insert(40); s1.insert(30); s1.insert(20); s1.insert(30); // 遍历容器 // set容器特点:所有的元素插入的时候自动排序 // set容器不允许插入重复值 printSet(s1);// 10 20 30 40 // 拷贝构造 set<int>s2(s1); printSet(s2);// 10 20 30 40 // 赋值 set<int>s3; s3 = s2; printSet(s3);// 10 20 30 40 } int main() { test01(); system("pause"); return 0; }

3. set大小和交换

功能描述:

  • 统计set容器大小以及交换set容器

函数原型:

  • size(); 返回容器中元素的数目
  • empty(); 判断容器是否为空
  • swap(st); 交换两个集合容器

总结:

  • 统计大小 — size
  • 判断是否为空 — empty
  • 交换容器 — swap
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include<iostream> #include<set> using namespace std; // set容器 大小和交换 void printSet(set<int>& s) { for (set<int>::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } // 大小 void test01() { // 只能用insert插入数据 set<int>s1; s1.insert(10); s1.insert(30); s1.insert(20); s1.insert(40); printSet(s1);// 打印容器 // 判断是否为空 if (s1.empty()) { cout << "s1为空" << endl; } else { cout << "s1不为空" << endl; cout << "s1的大小为:" << s1.size() << endl; } } // 交换 void test02() { // s2插入数据 set<int>s2; s2.insert(10); s2.insert(30); s2.insert(20); s2.insert(40); // s3插入数据 set<int>s3; s3.insert(100); s3.insert(300); s3.insert(200); s3.insert(400); cout << "交换前:" << endl; printSet(s2); printSet(s3); cout << "交换后:" << endl; s2.swap(s3); printSet(s2); printSet(s3); } int main() { test01(); test02(); system("pause"); return 0; }

在这里插入图片描述

4. set插入和删除

功能描述:

  • set容器进行插入数据和删除数据

函数原型:

  • insert(elem); 在容器中插入元素。
  • clear(); 清除所有元素
  • erase(pos); 删除pos迭代器所指的元素,返回下一个元素的迭代器。
  • erase(beg, end); 删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
  • erase(elem); 删除容器中值为elem的元素。

总结:

  • 插入 — insert
  • 删除 — erase
  • 清空 — clear
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<iostream> #include<set> using namespace std; // set容器的插入和删除 void printSet(set<int>& s) { for (set<int>::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { // s1插入数据 set<int>s1; s1.insert(10); s1.insert(30); s1.insert(20); s1.insert(40); printSet(s1);// 遍历 10 20 30 40 // 删除 s1.erase(s1.begin()); printSet(s1);// 20 30 40 插入后都会被排序 // 删除的重载版本 s1.erase(30);// 迭代器版本 printSet(s1);// 20 40 // 清空 // s1.erase(s1.begin(), s1.end()); s1.clear(); printSet(s1); } int main() { test01(); system("pause"); return 0; }

在这里插入图片描述

5. set查找和统计

功能描述:

  • 对set容器进行查找数据以及统计数据

函数原型:

  • find(key); 查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
  • count(key); 统计key的元素个数

总结:

  • 查找 — find (返回的是迭代器)
  • 统计 — count (对于set,结果为0或者1)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<iostream> #include<set> using namespace std; // 查找 void test01() { // s1插入数据 set<int>s1; s1.insert(10); s1.insert(30); s1.insert(20); s1.insert(40); set<int>::iterator pos = s1.find(30);// 查找 if (pos != s1.end()) { cout << "找到元素:" << *pos << endl;// 找到迭代器的位置 } else { cout << "未找到元素" << endl; } } // 统计 void test02() { set<int>s2; // 插入数据 s2.insert(10); s2.insert(30); s2.insert(20); s2.insert(40); s2.insert(30); s2.insert(30); // 统计30 的个数 int num = s2.count(30); // 对于set而言 统计的结果要么是0,要么是1,对于重复的数只算一次。 cout << "num = " << num << endl; } int main() { test01(); test02(); system("pause"); return 0; }

在这里插入图片描述

6. set与multiset区别

学习目标:

  • 掌握set和multiset的区别

区别:

  • set不可以插入重复数据,而multiset可以
  • set插入数据的同时会返回插入结果,表示插入是否成功
  • multiset不会检测数据,因此可以插入重复数据

总结:

  • 如果不允许插入重复数据可以利用set
  • 如果需要插入重复数据利用multiset
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<iostream> #include<set> using namespace std; // set容器和multiset容器的区别 void test01() { set<int>s; // pair为对组,iterator为迭代器,bool为布尔函数 pair<set<int>::iterator, bool> ret = s.insert(10); if (ret.second)// 主要看bool,ret第2个数据 { cout << "第一次插入成功" << endl; } else { cout << "第一次插入失败" << endl; } ret = s.insert(10); if (ret.second) { cout << "第二次插入成功" << endl; } else { cout << "第二次插入失败" << endl; } multiset<int>ms; // 允许插入重复值 ms.insert(10); ms.insert(10); for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }

在这里插入图片描述

7. pair对组创建

功能描述:

  • 成对出现的数据,利用对组可以返回两个数据

两种创建方式:

  • pair<type, type> p ( value1, value2 );
  • pair<type, type> p = make_pair( value1, value2 );
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<vector> #include<algorithm>//算法头文件 #include<iostream> #include<string> using namespace std; // pair对组的创建 void test01() { // 第一种方式 pair<string, int>p1("Tom", 20); cout << "姓名" << p1.first << "年龄:" << p1.second << endl; // 第二种方式 pair<string, int>p2 = make_pair("Jerry", 30); cout << "姓名" << p2.first << "年龄:" << p2.second << endl; } int main() { test01(); system("pause"); return 0; }

在这里插入图片描述

8. set容器排序

学习目标:

  • set容器默认排序规则为从小到大,掌握如何改变排序规则

主要技术点:

  • 利用仿函数,可以改变排序规则

8.1 内置类型指定排序

  • 报错的话,在仿函数参数列表后面加const:bool operator()(int v1,int v2)const
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include<iostream> #include<set> using namespace std; // set容器排序 // 仿函数形式写从大到小的排列 // 仿函数是bool类型 class MyCompare { public: bool operator()(int v1,int v2)const // 第一个()表示重载的符号,第二个()表示函数的参数列表 { return v1 > v2;// 做降序排列,当第一个数大于第二个数的时候,return真,否则return假 } }; void test01() { set<int>s1; s1.insert(10); s1.insert(40); s1.insert(20); s1.insert(50); s1.insert(30); // 打印函数 for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) { cout << *it << " "; } cout << endl; // 指定排序规则为从大到小 set<int, MyCompare>s2;// 把仿函数放到第二个位置,仿函数做从大到小排序 s2.insert(10); s2.insert(40); s2.insert(20); s2.insert(50); s2.insert(30); for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; }

在这里插入图片描述

8.2 自定义数据类型指定排序

  • 自定义数据类型,都会指定排序规则,不指定排序规则的话会报错
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<iostream> #include<set> #include<string> using namespace std; // set容器排序,存放自定义数据类型 class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } string m_Name; int m_Age; }; // 写仿函数指定排序规则 仿函数本质是类,返回bool类型 class comparePerson { public: // 引用方式做传递,加const不能修改 bool operator()(const Person& p1, const Person& p2)const// 最后一定要加const { // 按照年龄降序 return p1.m_Age > p2.m_Age; } }; void test01() { // 自定义数据类型,都会指定排序规则,不指定排序规则的话会报错 set<Person,comparePerson>s; // 创建Person对象 Person p1("刘备", 24); Person p2("关羽", 28); Person p3("张飞", 25); Person p4("赵云", 21); s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); for (set<Person,comparePerson>::iterator it = s.begin(); it != s.end(); it++) { cout << "姓名: " << it->m_Name << " 年龄:" << it->m_Age << endl; } } int main() { test01(); system("pause"); return 0; }

在这里插入图片描述

二、map/multimap容器

1. map基本概念

简介:

  • map中所有元素都是pair
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  • 所有元素都会根据元素的键值自动排序

本质:

  • map/multimap属于关联式容器,底层结构是用二叉树实现。

优点:

  • 可以根据key值快速找到value值

map和multimap区别:

  • map不允许容器中有重复key值元素
  • multimap允许容器中有重复key值元素

2. map构造和赋值

功能描述:

  • 对map容器进行构造和赋值操作

函数原型:

构造:

  • map<T1, T2> mp; map默认构造函数:
  • map(const map &mp); 拷贝构造函数

赋值:

  • map& operator=(const map &mp); 重载等号操作符

总结:

  • map中所有元素都是成对出现,插入数据时候要使用对组
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<iostream> #include<map> using namespace std; // map容器 构造和赋值,map中元素都是pair // 打印容器 void printMap(map<int, int>& m) { for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << "key = " << (*it).first << " value = " << it->second << endl; } cout << endl; } void test01() { // 创建map容器 map<int, int>m;// 第一个是key值,第二个是value值 // 匿名的对组放入到容器中,1起到索引作用,10是实值 m.insert(pair<int, int>(1, 10)); m.insert(pair<int, int>(2, 20)); m.insert(pair<int, int>(3, 30)); m.insert(pair<int, int>(4, 40)); printMap(m); // 拷贝构造 map<int, int>m2(m); printMap(m2); // 赋值 map<int, int>m3; m3 = m2; printMap(m3); } int main() { test01(); system("pause"); return 0; }

在这里插入图片描述

3. map大小和交换

功能描述:

  • 统计map容器大小以及交换map容器

函数原型:

  • size(); 返回容器中元素的数目
  • empty(); 判断容器是否为空
  • swap(st); 交换两个集合容器
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include<iostream> #include<map> using namespace std; // map容器大小和交换 // 打印容器 void printMap(map<int, int>& m) { for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << "key = " << (*it).first << " value = " << it->second << endl; } cout << endl; } // 大小 void test01() { map<int, int>m; m.insert(pair<int, int>(1, 10)); m.insert(pair<int, int>(2, 20)); m.insert(pair<int, int>(3, 30)); m.insert(pair<int, int>(4, 40)); if (m.empty()) { cout << "m为空" << endl; } else { cout << "m不为空" << endl; cout << "m的大小为:" << m.size() << endl; } } // 交换 void test02() { map<int, int>m1; m1.insert(pair<int, int>(1, 10)); m1.insert(pair<int, int>(2, 20)); m1.insert(pair<int, int>(3, 30)); m1.insert(pair<int, int>(4, 40)); map<int, int>m2; m2.insert(pair<int, int>(5, 50)); m2.insert(pair<int, int>(6, 60)); m2.insert(pair<int, int>(7, 70)); m2.insert(pair<int, int>(8, 80)); cout << "交换前:" << endl; printMap(m1); printMap(m2); m1.swap(m2);//m1和m2交换 cout << "交换后:" << endl; printMap(m1); printMap(m2); } int main() { test01(); test02(); system("pause"); return 0; }

在这里插入图片描述

4. map插入和删除

功能描述:

  • map容器进行插入数据和删除数据

函数原型:

  • insert(elem); 在容器中插入元素。
  • make_pair() 插入元素(建议使用)
  • clear(); 清除所有元素
  • erase(pos); 删除pos迭代器所指的元素,返回下一个元素的迭代器。
  • erase(beg, end); 删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
  • erase(key); 删除容器中值为key的元素。

总结:

  • map插入方式很多,记住其一即可
  • 插入 — insert
  • 删除 — erase
  • 清空 — clear
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include<iostream> #include<map> using namespace std; // map容器插入和删除 void printMap(map<int, int>& m)// 打印函数 { for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << "key = " << it->first << " value = " << it->second << endl; } cout << endl; } void test01() { // 插入 map<int, int>m; // 第一种 m.insert(pair<int, int>(1, 10)); // 第二种(建议) m.insert(make_pair(2, 20)); // 第三种(不建议使用) m.insert(map<int, int>::value_type(3, 30)); // 第四种(不建议使用) m[4] = 40; // []不建议插入,用途 可以利用key访问到value printMap(m); // 删除 m.erase(m.begin()); printMap(m); m.erase(3);// 按照key删除 printMap(m); // 清空 m.erase(m.begin(), m.end()); // m.clear(); printMap(m); } int main() { test01(); system("pause"); return 0; }

5. map查找和统计

功能描述:

  • 对map容器进行查找数据以及统计数据

函数原型:

  • find(key); 查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
  • count(key); 统计key的元素个数
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream> #include<map> using namespace std; // map容器 查找和统计,根据key值进行统计和查找 void test01() { map<int, int>m; m.insert(pair<int, int>(1, 10)); m.insert(pair<int, int>(2, 20)); m.insert(pair<int, int>(3, 30)); map<int, int>::iterator pos = m.find(3);// 找key=3,返回的是迭代器。无论是否找到都返回迭代器 if (pos != m.end())// 迭代器的位置是否为end,迭代器可以理解为是指针 { cout << "查到了元素 key = " << (*pos).first << " value = " << pos->second << endl; } else { cout << "未找到元素" << endl; } // 统计 // map不允许插入重复key元素,count统计而言,结果要么是1,要么是0 // multimap的count统计可能大于1 int num = m.count(3); cout << "num = " << num << endl; } int main() { test01(); system("pause"); return 0; }

在这里插入图片描述

6. map排序

学习目标:

  • map容器默认排序规则为 按照key值进行 从小到大排序,掌握如何改变排序规则

主要技术点:

  • 利用仿函数,可以改变排序规则
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream> #include<map> using namespace std; // 仿函数 class MyCompare { public: bool operator()(int v1, int v2)const // 最后一定要加 const { // 降序 return v1 > v2;// 第一个数字大于第二个数字为真,否则为假 } }; void test01() { map<int, int, MyCompare>m;// 默认的是从小到大排序 // 等同于pair<int,int>(1,10),第1个数字是key值 m.insert(make_pair(1, 10)); m.insert(make_pair(2, 20)); m.insert(make_pair(3, 30)); m.insert(make_pair(4, 40)); m.insert(make_pair(5, 50)); for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) { cout << "key = " << it->first << " value = " << (*it).second << endl; } } int main() { test01(); system("pause"); return 0; }

在这里插入图片描述

三、案例——员工分组

1. 案例描述

  • 公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作
  • 员工信息有: 姓名 工资组成;部门分为:策划、美术、研发
  • 随机给10名员工分配部门和工资
  • 通过multimap进行信息的插入 key(部门编号) value(员工)
  • 分部门显示员工信息

2. 实现步骤

  1. 创建10名员工,放到vector中
  2. 遍历vector容器,取出每个员工,进行随机分组
  3. 分组后,将员工部门编号作为key,具体员工作为value,放入到multimap容器中
  4. 分部门显示员工信息
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include<iostream> #include <vector> #include <string> #include <map> #include <ctime> using namespace std; /* - 公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作 - 员工信息有: 姓名 工资组成;部门分为:策划、美术、研发 - 随机给10名员工分配部门和工资 - 通过multimap进行信息的插入 key(部门编号) value(员工) - 分部门显示员工信息 */ #define CEHUA 0 #define MEISHU 1 #define YANFA 2 class Worker { public: string m_Name; int m_Salary; }; void createWorker(vector<Worker>&v) { string nameSeed = "ABCDEFGHIJ"; for (int i = 0; i < 10; i++) { Worker worker; worker.m_Name = "员工"; worker.m_Name += nameSeed[i]; worker.m_Salary = rand() % 10000 + 10000; // 10000 ~ 19999 // 将员工放入到容器中 v.push_back(worker); } } // 员工分组 void setGroup(vector<Worker>&v,multimap<int,Worker>&m) { for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++) { // 产生随机部门编号 int deptId = rand() % 3; // 0 1 2 // 将员工插入到分组中 // key部门编号,value具体员工 m.insert(make_pair(deptId, *it)); } } void showWorkerByGourp(multimap<int,Worker>&m) { // 0 A B C 1 D E 2 F G ... cout << "策划部门:" << endl; multimap<int,Worker>::iterator pos = m.find(CEHUA); int count = m.count(CEHUA); // 统计具体人数 int index = 0; for (; pos != m.end() && index < count; pos++ , index++) { cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl; } cout << "----------------------" << endl; cout << "美术部门: " << endl; pos = m.find(MEISHU); count = m.count(MEISHU); // 统计具体人数 index = 0; for (; pos != m.end() && index < count; pos++, index++) { cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl; } cout << "----------------------" << endl; cout << "研发部门: " << endl; pos = m.find(YANFA); count = m.count(YANFA); // 统计具体人数 index = 0; for (; pos != m.end() && index < count; pos++, index++) { cout << "姓名: " << pos->second.m_Name << " 工资: " << pos->second.m_Salary << endl; } } int main() { srand((unsigned int)time(NULL)); // 1、创建员工 vector<Worker>vWorker; createWorker(vWorker); // 2、员工分组 multimap<int, Worker>mWorker; setGroup(vWorker, mWorker); // 3、分组显示员工 showWorkerByGourp(mWorker); system("pause"); return 0; }

最后

以上就是含糊烧鹅最近收集整理的关于黑马C++ 03 提高6 —— STL常用容器_set/multiset容器/map/multimap容器一、set/multiset容器二、map/multimap容器三、案例——员工分组的全部内容,更多相关黑马C++内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(78)

评论列表共有 0 条评论

立即
投稿
返回
顶部