(六)set容器

集合可以是由两个迭代器定义范围内的一系列对象,也可以是一种有特殊特征的容器类型。除了没有单独的键,set容器和map容器很相似。有序set的模板定义在set头文件,无序set的模板定义在unordered_set头文件中。因此有序set包含的元素必须支持比较运算,无序set中的元素必须支持哈希运算。

定义set容器的模板如下:

set<T>容器保存T类型的对象,而且保存的对象时唯一的,其中保存的元素是有序的。可以用相等、不相等来判断对象是否相同。

multiSet<T>容器和set<T>容器保存T类型对象的方式相同,但它可以保存重复的对象。

unorderd_set<T>容器保存T类型的对象,而且对象时唯一的。元素在容器中的位置由元素的哈希值决定。默认用equal_to<T>对象来判断元素是否相等。

unorderd_multiset<T>容器保存T类型对象的方式和unorderd_set<T>相同,但它可以保存重复的对象。

1、set添加、删除和访问元素

添加元素

std::set<string,std::greater<string>> words={"one","two","three"};
auto pr1=words.insert("four");
words.insert({"five","six"});
string wrds[]={"eight","nine","ten"};
words.insert(std::begin(wrds),std::end(wrds));
std::set<std::pair<string,string>> names;
auto pr=names.emplace(“Lisa”,”Carr”);
auto iter=names.emplace_hint(pr.first,”Joe”,”King”);

删除元素

std::set<int> numbers={2,4,6,8,10,12,14};
auto iter=numbers.erase(++std::begin(numbers));  //删除迭代器指定位置的元素
auto n=numbers.erase(12);                    //删除对象匹配的元素
numbers.clear();                            //删除set的所有元素

访问元素

set的成员函数find()会返回一个和参数匹配的元素的迭代器。如果对象不在set中,会返回一个结束迭代器。

std::set<string> words={“one”,”two”,”three”,”four”,”five”};
auto iter=words.find(“one”);

2、set迭代器详解

set<T>容器的成员返回的迭代器都是双向迭代器。这些迭代器的类型的别名定义在set<T>模板中,可以从set中得到类型别名有iterator、reverse_iterator、const_iterator、const_reverse_iterator。例如:

成员函数begin()和end()返回iterator类型的迭代器。

成员函数rbegin()和rend()会返回reverse_iterator类型的迭代器。

成员函数cbegin()和cend()会返回const_iterator类型的迭代器。

成员函数crbegin()和crend()可以返回const_reverse_iterator类型的迭代器。

3、unordered_set定义及初始化详解

unordered_set<T>容器类型的模板定义在unordered_set头文件中。unordered_set<T>容器提供了和unordered_map<T>相似的能力,但unordered_set<T>可以保存的元素作为自己的键。T类型的对象在容器中的位置由它们的哈希值决定,因而需要定义一个Hash<T>函数。

std::unordered_set<string> words={“one”,”two”,”three”,”four”};
std::unordered_set<string> some_words={++std::begin(words),std::end(words)};

4、unordered_set插入元素

成员函数insert()可以插入作为参数传入的单个元素。在这种情况下,它会返回一个pair对象,这个pair对象包含一个迭代器,以及一个附加的布尔值用来说明插入是否成功。如果元素被插入,返回的迭代器会指向新元素;如果没有被插入,迭代器指向阻止插入的元素。可以用一个迭代器作为insert()的第一个参数,它指定元素被插入的位置,如果忽略插入位置,在这种情况下,只会返回一个迭代器。

auto pr=words.insert(“ninety”);
auto iter=words.insert(pr.first,”nine”);
words.insert({“ten”,”seven”,”six”});

unordered_set容器的成员函数emplace()和emplace_hint()可以在容器的适当位置创建元素。传入emplace()的参数会被传入元素的构造函数,用来创建元素。emplace_hint()的迭代器参数可以指定元素的插入位置,后面是构造元素需要的参数。

std::unordered_set<std::pair<string,string>> names;
auto pr=names.emplace(“Jack”,”Jones”);
auto iter=names.emplace_hint(pr.first,”John”,”Smith”);

5、unordered_set删除元素

调用unordered_set容器的成员函数clear()可以删除它的全部元素。成员函数erase()可以删除容器中和传入参数的哈希值相同的元素。

std::pair<string,string> person {“John”,”Smith”};
auto iter=name.find(person);
if(iter!=std::end(names)) names.erase(iter);

6、set_union算法详解

std::vector<int> set1 {1, 2, 3, 4, 5, 6};
std::vector<int> set2 {4, 5, 6, 7, 8, 9};
std::vector<int> result;
std::set_union(std::begin (set1), std::end(set1),std::begin(set2), std::end(set2), std::back_inserter(result));    
// Destination for the result:1 2 3 4 5 6 7 8 9

7、set_intersection用法详解

std::set<string> words1 {"one", "two", "three", "four", "five", "six"};
std::set<string> words2 {"four","five", "six", "seven", "eight", "nine"};
std::set<string> result;
std::set_intersection(std::begin(words1), std::end(words1), std::begin(words2), std::end(words2),std::inserter(result, std::begin(result))); // Result: "five" "four" "six"

8、set_difference

std::set<string, std::greater<string>> words1 {"one", "two", "three", "four", "five", "six" };
std::set<string, std::greater<string>> words2 { "four", "five", "six", "seven", "eight", "nine"};
std::set<string, std::greater<string>> result;
std::set_difference(std::begin(words1) , std::end(words1),
std::begin(words2), std::end(words2), std::inserter(result, std::begin(result)),std::greater<string>());
// Result: "two", "three", "one"

9、includes

比较两个元素的集合,如果第一个集合中全部元素都来自第二个集合,返回true。如果第二个集合是空的集合,返回true。

std::set<string> words1 { "one", "two", "three", "four", " five", "six"};
std::set<string> words2 {"four", "two", " seven"};
std::includes(std::begin(words1), std::end(words1), std::begin(words2), std::end(words2));

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值