首页 技术 正文
技术 2022年11月19日
0 收藏 847 点赞 3,995 浏览 3753 个字

目录


注:原创不易,转载请务必注明原作者和出处,感谢支持!

注:内容来自某培训课程,不一定完全正确!

一 set和multiset

set和multiset的特性是所有元素会根据元素的值自动进行排序。set和multiset以红黑树(平衡二叉树的一种)为底层机制。其查找效率非常好。set容器中不允许重复的元素,multiset则允许重复元素存在。

构造函数

set<T> st;// 默认构造函数
multiset<T> mst;// multiset默认构造函数
set(const set &st);// 拷贝构造函数

赋值操作

set &operator=(const set &st);// 重载等号运算符
swap(st);// 交换两个集合容器中的元素

大小操作

size();// 返回容器中元素的数目
empty();// 判断容器是否为空

插入和删除

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

查找操作

find(key);// 查找键key是否存在,若存在,返回该元素的迭代器;若不存在,则返回map.end()
lower_bound(keyElem);// 返回第一个key>=keyElem元素的迭代器
upper_bound(keyElem);// 返回第一个key>keyElem元素的迭代器
equal_range(keyElem);// 返回容器中key和keyElem相等的上下限的两个迭代器

下面是set和multiset的应用案例。

void printSet(set<int> &v)
{
decltype(v.begin()) it;
for (it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}void printMultiset(multiset<int> &mst)
{
decltype(mst.begin()) it;
for (it = mst.begin(); it != mst.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}void Test1()
{
// 初始化
set<int> s1;
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
printSet(s1);// 赋值
set<int> s2 = s1;
printSet(s2);set<int> s3;
s3.swap(s1);
printSet(s1);
printSet(s3);// 删除
s3.erase(s3.begin());
printSet(s3);
s3.erase(7);
printSet(s3);// multiset
multiset<int> mst;
mst.insert(7);
mst.insert(6);
mst.insert(9);
mst.insert(1);
mst.insert(6);
cout << "mst = " << endl;
decltype(mst.begin()) it;
for (it = mst.begin(); it != mst.end(); ++it)
{
cout << *it << " ";
}
cout << endl;// 查找
set<int> st;
for (int i = 1; i <= 10; ++i)
{
st.insert(i * 10);
}
printSet(st);set<int>::iterator itlow, itup;
// 第一个key >= 30的元素的迭代器
itlow = st.lower_bound(30);
// 第一个key > 60的元素的迭代器
itup = st.upper_bound(60);
cout << "*itlow = " << *itlow << endl;
cout << "*itup = " << *itup << endl;
st.erase(itlow, itup);
printSet(st);// equal_range()
multiset<int> s;
s.insert(10);
s.insert(20);
s.insert(20);
s.insert(20);
s.insert(30);
s.insert(40);
printMultiset(s);pair<decltype(s.begin()), decltype(s.begin())> iteq;
iteq = s.equal_range(20);
cout << "*iteq.first = " << *iteq.first << endl;
cout << "*iteq.second = " << *iteq.second << endl;
s.erase(iteq.first, iteq.second);
printMultiset(s);
}

使用仿函数更改set容器的默认排序方式

在上面的案例中,我们知道set容器默认是对int数据从小到大进行排序的。那么怎样才能让set从大到小排序呢?请看下面的例子。

// 仿函数
class MyCompare
{
public:
bool operator() (int v1, int v2)
{
return v1 > v2;
}
};// 从大到小排序
void Test2()
{
set<int, MyCompare> s1;
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
decltype(s1.begin()) it;
for (it = s1.begin(); it != s1.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}

set容器当中如何放置对象

如果你直接这样写的话是不行的!

class Person
{
public:
Person(int id, int age) : id(id), age(age) {}
public:
int id;
int age;
};void Test3()
{
// 会报错!因为set内部是需要排序的,当你往set里放置对象时,
// set是不知道如何对对象进行排序的。这与基础数据类型不同
set<Person> sp;
Person p1(1000, 20);
Person p2(1001, 21);
Person p3(1002, 22);
sp.insert(p1);
sp.insert(p2);
sp.insert(p3);
}

那这个问题如何解决?使用仿函数!如下所示。

class cmp
{
public:
bool operator() (const Person &p1, const Person &p2)
{
// 根据ID从小到大排序
return p1.id < p2.id;
}
};void Test3()
{
// 会报错!因为set内部是需要排序的,当你往set里放置对象时,
// set是不知道如何对对象进行排序的。这与基础数据类型不同
// set<Person> sp;// 正确的写法
set<Person, cmp> sp;
Person p1(1000, 23);
Person p2(1001, 26);
Person p3(1002, 22);
sp.insert(p1);
sp.insert(p2);
sp.insert(p3);decltype(sp.begin()) it;
for (it = sp.begin(); it != sp.end(); ++it)
{
cout << "id = " << it->id << " " << "age = " << it->age << endl;
}// 务必注意:因为仿函数cmp里只对Person的ID进行比较
// 所以在下面的案例中,在sp中查找p4,结果理应是p4不在
// sp中的。但是,因为cmp直对Person的ID进行比较,所以
// 下面案例的实际输出是p4在sp中!,因为p4的ID和p3的ID
// 相同。所以,it返回的实际上是p3的迭代器!!!!!!
Person p4(1002, 29);
it = sp.find(p4);
if (it != sp.end())
{
cout << "p4在sp中!" << endl;
cout << "id = " << it->id << " " << "age = " << it->age << endl;
}
else
{
cout << "p4不在sp中!" << endl;
}
}

务必注意上面案例中的查找的注意事项!

二 对组pair

对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可以分别用pair的两个公有函数first和second访问。

创建对组

// 方法一
pair<string, int> p1(string("name"), 20);
cout << p1.first << endl;
cout << p1.second << endl;// 方法二
pair<string, int> p2 = make_pair("name", 20);
cout << p2.first << endl;
cout << p2.second << endl;// 对组的赋值
pair<string, int> p3 = p2;
cout << p3.first << endl;
cout << p3.second << endl;
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,489
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,904
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,737
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,490
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,128
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,291