电子说
set/multiset容器又称为关联式容器,底层是通过二叉树实现。set/multiset容器在插入数据时就会做排序处理,默认是从小到大的顺序。其中set容器允许插入重复数据,multiset则不做此限制。
在前面介绍的string(字符串)、vector(单端数组)、deque(双端数组)、statck(栈)、queue(队列)、list(链表)都属于顺序容器。而set/multiset则是数组关联式容器。
set容器支持默认构造、有参构造、拷贝构造三种方式。
set容器插入数据使用insert()函数。
set/multiset是一个关联式容器,在插入数据时就会自动排序,底层实现原理是二叉树
set不允许插入重复数据(插入重复数据会忽略)
multiset则可以插入重复数据
set/multiset构造函数
默认构造:set< T > t;
有参构造:set(begin,end);
拷贝构造函数set(const set &p);
set/multiset赋值:
重载=: set &operator=(const set &p);
#include < iostream >
using namespace std;
#include < set >
void PrintSet(const set< int >& p)
{
for (set< int >::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < < *ptr < < " ";
}
cout < < endl;
}
void PrintMultiset(multiset< int >& p)
{
for (multiset< int >::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < < *ptr < < " ";
}
cout < < endl;
}
void test()
{
set< int > t1;
//插入数据
t1.insert(10);
t1.insert(5);
t1.insert(7);
t1.insert(8);
t1.insert(10);
PrintSet(t1);
cout < < "有参构造:" < < endl;
set< int >t2(t1.begin(), t1.end());
PrintSet(t2);
cout < < "拷贝构造:" < < endl;
set< int >t3(t2);
PrintSet(t3);
multiset< int >mt1;
mt1.insert(10);
mt1.insert(5);
mt1.insert(7);
mt1.insert(8);
mt1.insert(10);
cout < < "multiset容器示例:" < < endl;
PrintMultiset(mt1);
cout < < "=赋值示例:" < < endl;
multiset< int >mt2 = mt1;//等号赋值
PrintMultiset(mt2);
}
int main()
{
test();
system("pause");
}
set/multiset大小设置:
获取元素个数:size()
判断容器是否为空empty();
互换元素:swap()
#include < iostream >
using namespace std;
#include < set >
#if 1
void PrintSet(const set< int >& p)
{
for (set< int >::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < < *ptr < < " ";
}
cout < < endl;
}
void test()
{
set< int > t1;
for (int i = 0; i < 5; i++)
{
int temp = rand() % 100;
t1.insert(temp);
}
cout < < "元素个数:" < < t1.size() < < endl;
cout < < "t1数据信息:" < < endl;
PrintSet(t1);
set< int > t2;
if (t2.empty())
{
cout < < "t2容器为空" < < endl;
}
cout < < "t2赋值" < < endl;
t2 = t1;
cout < < "t2数据信息:" < < endl;
PrintSet(t2);
cout < < "swap数据互换:" < < endl;
set< int >t3;
t3.swap(t2);
cout < < "t3数据信息:" < < endl;
PrintSet(t3);
cout < < "t2数据信息:" < < endl;
PrintSet(t2);
cout < < "t2元素个数:" < ()< <>
4.set容器设置大小和互换元素
insert()插入元素,可以插入单端数据,也可以插入一个区间数据。
erase()删除元素,可以指定位置删除,可以删除所以相同的元素,也可以删除一个区间范围。
clear()清空容器。
set容器插入:
insert(elem) -- >插入数据elem
insert(begin,endl)--- >插入区间
注意:set容器没有push_back、push_front函数
set容器删除:
erase(elem);//删除成员,相当于list容器的remove
erase(begin,end);//删除区间
erase(pos);//指定位置删除
clear();//清空
#include < iostream >
using namespace std;
#include < set >
class Person
{
public:
Person(string name, int age) :name(name), age(age) {
}
//setr容器由于插入数据时会对数据进行排序,所以需要重载"< ",而且必须为常函数
bool operator< (const Person& p)const
{
if (name == p.name)return age < p.age;
else name < p.name;
}
bool operator==(const Person& p)const
{
if (name == p.name && age == p.age)return true;
return false;
}
string name;
int age;
};
ostream& operator< <(ostream& cout, const Person& p)
{
cout < < "姓名:" < < p.name < < "t年龄:" < < p.age;
return cout;
}
void PrintSet(set< Person >& p)
{
for (set< Person >::iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < < *ptr < < endl;
}
}
void test()
{
set< Person > t1;
t1.insert(Person("小王",18));
t1.insert(Person("小李", 18));
t1.insert(Person("小李", 19));
t1.insert(Person("小王", 18));
PrintSet(t1);
set< Person >t2;
t2.insert(t1.begin(), t1.end());
cout < < "t2数据内容:" < < endl;
PrintSet(t2);
cout < < "t2删除成员:" < < endl;
t2.erase(Person("小李", 18));
PrintSet(t2);
cout < < "t2删除区间:" < < endl;
t2.erase(t2.begin(), t2.end() );//相当于clear()
PrintSet(t2);
cout < < "t1指定位置删除:" < < endl;
t1.erase(t1.begin());
PrintSet(t1);
}
int main()
{
test();
system("pause");
}
5.查找和统计元素个数
find()函数查找元素,查找冲个返回该元素的位置迭代器,失败返回end;
count()函数通过成员,返回个数。
set容器查找:
set< T >::iterator &find(elem) -- >查找成功返回该成员的迭代器,若不存在返回end()
set容器统计
count(elem) --- >统计elem的个数
#include < iostream >
using namespace std;
#include < set >
class Person
{
public:
Person(string name, int age) :name(name), age(age) {
}
bool operator< (const Person& p)const
{
if (age == p.age)
{
return name < p.name;//年龄相同按姓名降序
}
return age < p.age;
}
string name;
int age;
};
ostream& operator< <(ostream& cout, const Person& p)
{
cout < < "姓名:" < < p.name < < "t年龄:" < < p.age;
return cout;
}
void PrintSet(set< Person >& t)
{
for (set< Person >::iterator ptr = t.begin(); ptr != t.end(); ptr++)
{
cout < < *ptr < < endl;
}
}
void test()
{
set< Person > t1;
t1.insert(Person("小王", 18));
t1.insert(Person("小李", 18));
t1.insert(Person("小李", 19));
t1.insert(Person("小王", 18));
PrintSet(t1);
auto ret= t1.find(Person("小李", 19));//此时auto ret等价于set< Person >::iterator ret;
if (ret != t1.end())
{
cout < < "查找成功:";
cout < < *ret < < endl;
}
else
{
cout < < "查找失败!" < < endl;
}
int count = t1.count(Person("小李", 19));
cout < < "满足的成员个数:"< & t)
{
for (multiset< Person >::iterator ptr = t.begin(); ptr != t.end(); ptr++)
{
cout < < *ptr < < endl;
}
}
void test2()
{
multiset< Person > mt;
mt.insert(Person("小王", 18));
mt.insert(Person("小李", 18));
mt.insert(Person("小李", 19));
mt.insert(Person("小王", 18));
PrintMultiset(mt);
cout < < "统计所有的Person("小王", 18)成员" < < endl;
auto ret = mt.count(Person("小王", 18));
cout < < "个数为:" < < ret < < endl;
cout < < "删除所有的Person("小王", 18)成员" < < endl;
for (auto ptr = mt.begin(); ptr != mt.end(); )
{
auto ret = mt.find(Person("小王", 18));
if (ret != mt.end())
ptr=mt.erase(ret);//删除该成员,成功返回下一个成员的迭代器
else ptr++;
}
PrintMultiset(mt);
}
int main()
{
test();
cout < < "n------------------------multiset容器---------------------" < < endl;
test2();
system("pause");
}<
6.set和multiset区别
set和multiset区别:
set不可以插入重复数据,insert插入数据时有返回值。返回类型为队组pair,该返回值返回的是插入数据的位置迭代器,第二是插入的状态值;
multiset可以插入重复数据,insert插入数据返回值为插入数据的位置迭代器;,>
#include < iostream >
using namespace std;
#include < set >
#if 0
class Person
{
public:
Person(string name, int age) :name(name), age(age) {
}
bool operator< (const Person& p)const
{
//按年龄排序,年龄相同时再按姓名升序
if (age == p.age)return name < p.name;
return age < p.age;
}
string name;
int age;
};
ostream& operator< <(ostream& cout, const Person &p)
{
cout < < "姓名:" < < p.name < < "t年龄:" < < p.age;
return cout;
}
void PrintSet(set< Person >& p)
{
for (set< Person >::iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < < *ptr < < endl;
}
}
void test()
{
cout < < "set容器,不允许插入重复内容" < < endl;
set< Person > t1;
pair < set< Person >::iterator, bool > ret=t1.insert(Person("小王", 18));
if (ret.second)
{
cout < < "插入成功!" < < endl;
cout < < "插入的值为:" < < *(ret.first) < < endl;
}
ret = t1.insert(Person("小王", 18));
if (ret.second)
{
cout < < "第二次插入成功!" < < endl;
cout < < "插入的值为:" < < *(ret.first) < < endl;
}
else
{
cout < < "第二次插入失败!" < < endl;
cout < < "插入的值为:" < < *(ret.first) < < endl;
}
cout < < "ptr内容:" < < endl;
PrintSet(t1);
cout < < "multiset容器,允许插入重复内容" < < endl;
multiset< Person > mt;
auto point=mt.insert(Person("小王", 18));//返回当前位置迭代器iterator
cout < < "插入数据为:" < < *point < < endl;
point = mt.insert(Person("小王", 18));//返回当前位置迭代器iterator
cout < < "插入数据为:" < < *point < < endl;
cout < < "multiset容器内容:" < < endl;
for (multiset< Person >::iterator ptr = mt.begin(); ptr != mt.end(); ptr++)
{
cout < < *ptr < < endl;
}
}
int main()
{
test();
system("pause");
}
7.pair对组使用
对组pair--成对出现的数据,通过队组可以返回两个数据
对组创建:
pair p(val,val2);--有参构造
pairp=make_pair(val,val2),type>,type>
#include < iostream >
using namespace std;
void test()
{
pair< string, int > p("小王", 18);
cout < < "第一个参数:" < < p.first < < "t第二个参数:" < < p.second < < endl;
pair< string, int >p2 = make_pair("小李", 26);
cout < < "第一个参数:" < < p2.first < < "t第二个参数:" < < p2.second < < endl;
}
int main()
{
test();
system("pause");
}
8.set容器排序规则设置
set容器默认是升序排序,要实现降序排序则需要设置排序规则:提供一个仿函数。
#include < iostream >
using namespace std;
#include < set >
class mycompare
{
public:
bool operator()(int v1,int v2)const //仿函数,即重载()运算符
{
return v1 > v2;
}
};
void test()
{
set< int >t1;
t1.insert(20);
t1.insert(10);
t1.insert(40);
t1.insert(30);
t1.insert(5);
cout < < "默认排序:" < < endl;
for (set< int >::iterator ptr = t1.begin();ptr != t1.end(); ptr++)
{
cout < < *ptr< <" ";
}
cout < < endl;
set< int, mycompare >t2;
t2.insert(20);
t2.insert(10);
t2.insert(40);
t2.insert(30);
cout < < "从大到小排序:" < < endl;
for (set< int,mycompare >::iterator ptr = t2.begin(); ptr != t2.end(); ptr++)
{
cout < < *ptr < <" ";
}
cout < < endl;
}
int main()
{
test();
system("pause");
}
9.set容器自定义数据排序示例
对自定义数据类型进行数据排序。
#include < iostream >
using namespace std;
#include < set >
class Person
{
friend class mycompare;//定义为友元类
friend ostream& operator< <(ostream& cout, Person p);//友元函数
public:
Person(string name, int age) :name(name), age(age) {
}
private:
string name;
int age;
};
ostream& operator< <(ostream& cout, Person p)
{
cout < < "姓名:" < < p.name < < "t年龄:" < < p.age;
return cout;
}
class mycompare
{
public:
bool operator()(const Person& p1, const Person& p2)const
{
//年龄按降序,名字按升序
if (p1.age == p2.age)
{
return p1.name < p2.name;
}
return p1.age > p2.age;
}
};
void PrintSet(set< Person, mycompare >t)
{
for (set< Person, mycompare >::iterator ptr = t.begin(); ptr != t.end(); ptr++)
{
cout < < *ptr < < endl;
}
}
void test()
{
set< Person,mycompare >t1;
t1.insert(Person("小王", 18));
t1.insert(Person("小李", 18));
t1.insert(Person("小李", 19));
t1.insert(Person("小王", 18));
PrintSet(t1);
}
int main()
{
test();
system("pause");
}
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !