1.set/multiset容器簡介
set/multiset容器又稱為關聯式容器,底層是通過二叉樹實現。set/multiset容器在插入數據時就會做排序處理,默認是從小到大的順序。其中set容器允許插入重復數據,multiset則不做此限制。
在前面介紹的string(字符串)、vector(單端數組)、deque(雙端數組)、statck(棧)、queue(隊列)、list(鏈表)都屬于順序容器。而set/multiset則是數組關聯式容器。
2.set/multiset構造函數和賦值
set容器支持默認構造、有參構造、拷貝構造三種方式。
set容器插入數據使用insert()函數。
set/multiset是一個關聯式容器,在插入數據時就會自動排序,底層實現原理是二叉樹
set不允許插入重復數據(插入重復數據會忽略)
multiset則可以插入重復數據
set/multiset構造函數
默認構造:set t;
有參構造:set(begin,end);
拷貝構造函數set(const set &p);
set/multiset賦值:
重載=: set &operator=(const set &p);
#include
using namespace std;
#include
void PrintSet(const set& p)
{
for (set::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < *ptr < " ";
}
cout < endl;
}
void PrintMultiset(multiset& p)
{
for (multiset::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < *ptr < " ";
}
cout < endl;
}
void test()
{
set t1;
//插入數據
t1.insert(10);
t1.insert(5);
t1.insert(7);
t1.insert(8);
t1.insert(10);
PrintSet(t1);
cout < "有參構造:" < endl;
sett2(t1.begin(), t1.end());
PrintSet(t2);
cout < "拷貝構造:" < endl;
sett3(t2);
PrintSet(t3);
multisetmt1;
mt1.insert(10);
mt1.insert(5);
mt1.insert(7);
mt1.insert(8);
mt1.insert(10);
cout < "multiset容器示例:" < endl;
PrintMultiset(mt1);
cout < "=賦值示例:" < endl;
multisetmt2 = mt1;//等號賦值
PrintMultiset(mt2);
}
int main()
{
test();
system("pause");
}
3.set容器設置大小和互換元素
set/multiset大小設置:
獲取元素個數:size()
判斷容器是否為空empty();
互換元素:swap()
#include
using namespace std;
#include
#if 1
void PrintSet(const set& p)
{
for (set::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < *ptr < " ";
}
cout < endl;
}
void test()
{
set 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 t2;
if (t2.empty())
{
cout < "t2容器為空" < endl;
}
cout < "t2賦值" < endl;
t2 = t1;
cout < "t2數據信息:" < endl;
PrintSet(t2);
cout < "swap數據互換:" < endl;
sett3;
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
using namespace std;
#include
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& p)
{
for (set::iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < *ptr < endl;
}
}
void test()
{
set t1;
t1.insert(Person("小王",18));
t1.insert(Person("小李", 18));
t1.insert(Person("小李", 19));
t1.insert(Person("小王", 18));
PrintSet(t1);
sett2;
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::iterator &find(elem) -->查找成功返回該成員的迭代器,若不存在返回end()
set容器統計
count(elem) --->統計elem的個數
#include
using namespace std;
#include
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& t)
{
for (set::iterator ptr = t.begin(); ptr != t.end(); ptr++)
{
cout < *ptr < endl;
}
}
void test()
{
set 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::iterator ret;
if (ret != t1.end())
{
cout < "查找成功:";
cout < *ret < endl;
}
else
{
cout < "查找失敗!" < endl;
}
int count = t1.count(Person("小李", 19));
cout < "滿足的成員個數:"& t)
{
for (multiset::iterator ptr = t.begin(); ptr != t.end(); ptr++)
{
cout < *ptr < endl;
}
}
void test2()
{
multiset 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
using namespace std;
#include
#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& p)
{
for (set::iterator ptr = p.begin(); ptr != p.end(); ptr++)
{
cout < *ptr < endl;
}
}
void test()
{
cout < "set容器,不允許插入重復內容" < endl;
set t1;
pair ::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 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::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
using namespace std;
void test()
{
pair p("小王", 18);
cout < "第一個參數:" < p.first < "t第二個參數:" < p.second < endl;
pairp2 = make_pair("小李", 26);
cout < "第一個參數:" < p2.first < "t第二個參數:" < p2.second < endl;
}
int main()
{
test();
system("pause");
}
8.set容器排序規則設置
set容器默認是升序排序,要實現降序排序則需要設置排序規則:提供一個仿函數。
#include
using namespace std;
#include
class mycompare
{
public:
bool operator()(int v1,int v2)const //仿函數,即重載()運算符
{
return v1 > v2;
}
};
void test()
{
sett1;
t1.insert(20);
t1.insert(10);
t1.insert(40);
t1.insert(30);
t1.insert(5);
cout < "默認排序:" < endl;
for (set::iterator ptr = t1.begin();ptr != t1.end(); ptr++)
{
cout < *ptr<" ";
}
cout < endl;
sett2;
t2.insert(20);
t2.insert(10);
t2.insert(40);
t2.insert(30);
cout < "從大到小排序:" < endl;
for (set::iterator ptr = t2.begin(); ptr != t2.end(); ptr++)
{
cout < *ptr <" ";
}
cout < endl;
}
int main()
{
test();
system("pause");
}
9.set容器自定義數據排序示例
對自定義數據類型進行數據排序。
#include
using namespace std;
#include
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(sett)
{
for (set::iterator ptr = t.begin(); ptr != t.end(); ptr++)
{
cout < *ptr < endl;
}
}
void test()
{
sett1;
t1.insert(Person("小王", 18));
t1.insert(Person("小李", 18));
t1.insert(Person("小李", 19));
t1.insert(Person("小王", 18));
PrintSet(t1);
}
int main()
{
test();
system("pause");
}
審核編輯:湯梓紅
-
字符串
+關注
關注
1文章
584瀏覽量
20553 -
函數
+關注
關注
3文章
4338瀏覽量
62760 -
容器
+關注
關注
0文章
496瀏覽量
22078 -
C++
+關注
關注
22文章
2112瀏覽量
73717
發布評論請先 登錄
相關推薦
評論