C++中set使用及介绍(超详细+入门+代码解析)

C++中Set介绍

  • 1.文档介绍
    • 1.帮助文档
    • 2.总结:
    • 3.注意事项:
  • 2.构造函数介绍
  • 3.常用函数介绍
    • 3.1迭代器
    • 3.2容量
    • 3.3修改函数
      • 插入
      • 修改
      • 查找
        • lower_bound函数
        • upper_bound
      • 删除

1.文档介绍

C+帮助文档:链接: Set的文档介绍

1.帮助文档

C++中set使用及介绍(超详细+入门+代码解析)_第1张图片

2.总结:

  1. set是按照一定次序存储元素的容器
  2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素
    不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
  4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直
    接迭代。
  5. set在底层是用二叉搜索树(红黑树)实现的。

3.注意事项:

  1. 与map/multimap不同,map/multimap中存储的是真正的键值对,set中只放value,但
    在底层实际存放的是由构成的键值对。
  2. set中插入元素时,只需要插入value即可,不需要构造键值对。
  3. set中的元素不可以重复(因此可以使用set进行去重)。
  4. 使用set的迭代器遍历set中的元素,可以得到有序序列
  5. set中的元素默认按照小于来比较
  6. set中查找某个元素,时间复杂度为:log2N
  7. set中的元素不允许修改
  8. set中的底层使用二叉搜索树(红黑树)来实现。

2.构造函数介绍

#include 
#include 
#include 
#include 
 
template<typename Map>
void print_map(Map& m)
{
   std::cout << '{';
   for(auto& p: m)
        std::cout << p.first << ':' << p.second << ' ';
   std::cout << "}\n";
}
 
struct Point { double x, y; };
struct PointCmp {
    bool operator()(const Point& lhs, const Point& rhs) const { 
        return lhs.x < rhs.x; // NB 。有意忽略 y
    }
};
 
int main()
{
  // (1) 默认构造函数
  std::map<std::string, int> map1;
  map1["something"] = 69;
  map1["anything"] = 199;
  map1["that thing"] = 50;
  std::cout << "map1 = "; print_map(map1);
 
  // (2) 范围构造函数
  std::map<std::string, int> iter(map1.find("anything"), map1.end());
  std::cout << "\niter = "; print_map(iter);
  std::cout << "map1 = "; print_map(map1);
 
  // (3) 复制构造函数
  std::map<std::string, int> copied(map1);
  std::cout << "\ncopied = "; print_map(copied);
  std::cout << "map1 = "; print_map(map1);
 
  // (4) 移动构造函数
  std::map<std::string, int> moved(std::move(map1));
  std::cout << "\nmoved = "; print_map(moved);
  std::cout << "map1 = "; print_map(map1);
 
  // (5) initializer_list 构造函数
  const std::map<std::string, int> init {
    {"this", 100},
    {"can", 100},
    {"be", 100},
    {"const", 100},
  };
  std::cout << "\ninit = "; print_map(init);
 
 
  // 定制关键类选项 1 :
  // 使用比较 struct
  std::map<Point, double, PointCmp> mag = {
      { {5, -12}, 13 },
      { {3, 4},   5 },
      { {-8, -15}, 17 }
  };
 
  for(auto p : mag)
      std::cout << "The magnitude of (" << p.first.x
                << ", " << p.first.y << ") is "
                << p.second << '\n';
 
  // 定制关键类选项 2 :
  // 使用比较 lambda
  // 此 lambda 按照其模比较点,注意其中模取自局部变量 mag
  auto cmpLambda = [&mag](const Point &lhs, const Point &rhs) { return mag[lhs] < mag[rhs]; };
  // 你亦可使用不依赖局部变量的 lambda ,像这样:
  // auto cmpLambda = [](const Point &lhs, const Point &rhs) { return lhs.y < rhs.y; };
  std::map<Point, double, decltype(cmpLambda)> magy(cmpLambda);
 
  // 各种插入元素的方式:
  magy.insert(std::pair<Point, double>({5, -12}, 13));
  magy.insert({ {3, 4}, 5});
  magy.insert({Point{-8.0, -15.0}, 17});
 
  std::cout << '\n';
  for(auto p : magy)
      std::cout << "The magnitude of (" << p.first.x
                << ", " << p.first.y << ") is "
                << p.second << '\n';
}

输出:

map1 = {anything:199 something:69 that thing:50 }
 
iter = {anything:199 something:69 that thing:50 }
map1 = {anything:199 something:69 that thing:50 }
 
copied = {anything:199 something:69 that thing:50 }
map1 = {anything:199 something:69 that thing:50 }
 
moved = {anything:199 something:69 that thing:50 }
map1 = {}
 
init = {be:100 can:100 const:100 this:100 }
The magnitude of (-8, -15) is 17
The magnitude of (3, 4) is 5
The magnitude of (5, -12) is 13
 
The magnitude of (3, 4) is 5
The magnitude of (5, -12) is 13
The magnitude of (-8, -15) is 17

3.常用函数介绍

3.1迭代器

C++中set使用及介绍(超详细+入门+代码解析)_第2张图片

3.2容量

C++中set使用及介绍(超详细+入门+代码解析)_第3张图片

3.3修改函数

插入

C++中set使用及介绍(超详细+入门+代码解析)_第4张图片
需要注意的是,set容器的特点是,插入元素会自动进行排序,且不允许重复的元素插入。
C++中set使用及介绍(超详细+入门+代码解析)_第5张图片

修改

元素不支持修改 底层是一个const类型的迭代器;
C++中set使用及介绍(超详细+入门+代码解析)_第6张图片

查找

有两种查找的方式,一种是set库里给的find函数,时间复杂度是logN,另一种是用暴力查找的算法 复杂度是O(N);
C++中set使用及介绍(超详细+入门+代码解析)_第7张图片

lower_bound函数

帮助文档:C++中set使用及介绍(超详细+入门+代码解析)_第8张图片

lower_bound确定的范围是大于key的,相当于数学里的闭区间[ 。
例如:

// set::lower_bound/upper_bound
#include 
#include 

int main ()
{
  std::set<int> myset;
  std::set<int>::iterator itlow,itup;

  for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90

  itlow=myset.lower_bound (30);                //       ^
  itup=myset.upper_bound (60);                 //                   ^

  myset.erase(itlow,itup);                     // 10 20 70 80 90

  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: 10 20 70 80 90

upper_bound

确定范围比key大的,不包括key,相当于数学里的开区间(key

例如:

// set::lower_bound/upper_bound
#include 
#include 

int main ()
{
  std::set<int> myset;
  std::set<int>::iterator itlow,itup;

  for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90

  itlow=myset.lower_bound (30);                //       ^
  itup=myset.upper_bound (60);                 //                   ^

  myset.erase(itlow,itup);                     // 10 20 70 80 90

  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: 10 20 70 80 90

删除

删除有两种方式,一种是查找删除,一种是直接删除。
查找删除: C++中set使用及介绍(超详细+入门+代码解析)_第9张图片

查找删除,如果查找的数不存在set中就会报错!
直接删除:
C++中set使用及介绍(超详细+入门+代码解析)_第10张图片
直接删除,有就删,没有就不删,不会报错!
帮助文档:
C++中set使用及介绍(超详细+入门+代码解析)_第11张图片

创作不易,一起努力!转载请注明出处!谢谢支持!

你可能感兴趣的:(C+,数据结构,c++,开发语言,数据结构)