STL之set

为什么使用 set

set 是 C++ STL 内封装实现的平衡二叉树,效率较高,提供的成员函数(包括一些常用的操作:插入、删除和查找等)符合程序员的编程习惯,使用起来很方便。

为什么 set 的效率高

set 容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。因此在插入和删除元素时只是指针移动的操作,而不需要移动内存。

注意事项

set 可以理解为数学上的集合,每个元素最多只出现一次
自定义类型也可以使用 set,只需定义“小于”运算符即可。

常用操作

基本查询:
begin() 返回 set 容器的第一个元素(迭代器)
end() 返回 set 容器的最后一个元素(迭代器)
empty() 判断 set 容器是否为空
size() 返回当前 set 容器中的元素个数
count(x) 判断 set 容器中是否有键值为 x 的元素

插入删除:
insert(x) 向 set 容器中插入键值为 x 的元素
erase(it) 删除迭代器 it 指向的元素
erase(first,second) 删除迭代器 first 和 second 之间的元素
erase(x) 删除键值为 x 的元素
clear() 删除 set 容器中的所有的元素

二分查找:
lower_bound(x) 返回第一个大于等于 x 的迭代器
upper_bound(x) 返回最后一个大于等于x 的迭代器

使用样例
#include <iostream>
#include <set>

int main ()
{
  std::set<int> myset;

  myset.insert (100);
  myset.insert (200);
  myset.insert (300);

  std::cout << "myset contains:";
  for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it) //迭代器可以理解为“类似指针的东西”
    std::cout << ' ' << *it;
  std::cout << '\n';

  myset.clear();
  myset.insert (1101);
  myset.insert (2202);

  std::cout << "myset contains:";
  for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

输出结果:

myset contains: 100 200 300
myset contains: 1101 2202

例题:UVA10815

题目大意:输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出。单词不区分大小写。
分析:显然可以将单词插入一个 set 中,利用 set 中元素已从小到大排序这一性质,用一个 for 循环即可从小到大遍历输出所有元素。但本题的输入比较麻烦,如果不想手写输入,则可以使用速度较慢的 sstream,编写起来比较简单。
参考代码:

#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <set>
#include <sstream>
#include <string>

using namespace std;

typedef set <string> setstr;

setstr dict;
string str, temp;

int main(void) {
    dict.clear(); //初始化清空容器 
    while (cin >> str) {
        int len = str.size();
        for (int i = 0; i < len; i++)
            str[i] = isalpha(str[i]) ? tolower(str[i]) : ' ';
        //一方面将字母标准化统一变成小写,另一方面将符号统一变成空格方便sstream处理 
        stringstream ss;
        ss << str;
        while (ss >> temp) dict.insert(temp); //重复插入不会造成问题 
    }
    for (setstr::iterator it = dict.begin(); it != dict.end(); ++it)
        cout << *it << endl; //利用迭代器遍历输出 
    return 0;
}
参考资料
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值