• 由一段代码说开去——set


    #include <set>//包含了set类
    #include <iostream>
    #include <string>
    using namespace std;
    
    struct Info
    {
      string name;
      float score;
      bool operator<(const Info &a)const//默认按照less排列 所以你需要写上这个操作符重载 
      {
        return score<a.score;//保证了按score升序排列
      }
      bool operator>(const Info &a)const// greater模版需要写上这个操作符重载 
      {
        return score>a.score;//保证了按score降序排列
      }
      bool operator==(const Info &d)const//find会用==操作符重载进行比较
      {
        return score==d.score;
      }
    };
    int main()
    {
      Info info;
      set<Info,greater<Info> > s;//创建一个元素类型为Info的set对象 按关键字降序排列
       /******下面进行插入操作******/
      info.name="jack";
      info.score=59.9;
      s.insert(info);//
      info.name="rose";
      info.score=60.1;
      s.insert(info);
      /*下面是遍历输出*/
      set<Info>::iterator it=s.begin();
      for(;it!=s.end();it++)
      {
        cout<<(*it).name<<" ";
      }
      cout<<endl;
      //当然你也可以选择倒序遍历 只需要定义反向迭代器 reverse_iterator
      //同时使用方法 rbegin(),rend() 找到遍历的起始和终止
      /************下面进行反向遍历*************/
      
      set<Info>::reverse_iterator rt=s.rbegin();//声明一个反向迭代器
      for(;rt!=s.rend();rt++)//rt照常使用++ 因为反正是重载过的
      {
        cout<<(*rt).name<<" ";
      }
      cout<<endl;
      
      /****下面检索元素****/
      info.score=59.9;
      it=s.find(info);
      if(it!=s.end())
      {
        cout<<it->name<<endl;//像使用指针一样
      }
      else
      {
        cout<<"Not found.\n";
      }
      cin.get();
      return 0;
    }
    

    我觉得这段代码写的还是非常有意义的 首先使用的是c++结构体 而不是c++的类 或者c里面的结构体, 从而使用更加方便的去访问成员函数 同时具备成员方法;
    然后呢 set这个东西 一般是键值和元素类型一致 但是我们排序的时候 可以自定义排序方法,在构建的时候 就声明了这种方法。

    set呢是联合容器,不同于一般容器,它使用的是红黑树的平衡二叉检索树作为存储结构(和map一样)这样子就方便查找了find函数,这个比较重要需要==操作符的配合,  至于sort函数嘛 在这里我也不知道怎么用,大概是因为人家已经排好序了,这个显得不太重要;

    1.首先还是创建一个set对象:这个算是一个重点了,set<Info,greater<Info> > s;这里<>里面,用到了两个参数,一个表明元素类型,第二个表明排序方法,第二个参数是个模版类作为函数符,所以也要指明它的类型,它的类型呢当然也就是关键字类型了 而set的关键字类型和元素类型一致,所以就也是Info(map不是这样子),它的功能就是作为函数符 来告诉set 怎么对关键字进行排序;

    默认情况下是用的less模版类,使用<操作符进行升序排序的(可以不写第二个参数 如set<Info> info)排序用的比较函数就是对关键字 Info比较的方法 比如less模版类用的就是 操作符< ,如果元素类型是用户自定义的类型(结构体变量 类对象等) 那你就需要重载一下< 操作符了 

    当然 你也可以使用其他的函数符作为排序方法,可以是系统预定义的模版类(比如这里的greater降序排列,用的操作符是>, 常用的还有equal_to用的操作符是==),在自定义类型中使用这些模版类就需要虫子啊那些对应的操作符了 (个人觉得我的这句话技术含量还是蛮大的 哈哈)

    2.插入操作insert(),这个额,就不用像一般容器那样要求插入位置了,他会按照创建的时候声明的方法进行排序,并平衡二叉树(这样子中序遍历的结果就是排序的结果),一般我们只有一个参数就够了;

    3.遍历,就像代码里面说的和之前的一样 我们可以整序 倒序的遍历输出,用的迭代器和返回迭代器的方法自然不一样喽 这个没有技术难度,记住即可;

    4.这个呢算是另外一个重点了,find(),方法用在set里面还是比较多的,因为set本身就是为了检索而生的,其自身的二叉检索红黑树就决定了它是用来检索的;

    find()呢有三个点:(1).参数类型就是关键字类型 我们也说了,关键字类型就是元素类型,所以这里我们用元素类型,当然这并不是说我们是按元素类型比较大小的 比如这里的Info是个结构体 结构体是没有大小可言的,不过我们可以根据自己的需要找它的一个成员变量比较大小是吧,这样的效果就很好了(这样比map要好用呀)

    (2)==操作符重载,当元素类型是用户自定义的类型时 要把==操作符作为成员方法,因为find用的就是这个

    (3)返回值,如果找到,就返回对应的迭代器,当然只有一个喽 因为set就像集合一样,没有相等的元素(区别于multiset),如果没有找到返回超尾元素的迭代器;

    5.至于其他的那些erase(),clear()等方法 ,和一般容器都差不多,就不说了;

    6.小结一下,两个重点都是关于操作符的重载的 当时如果元素类型是基本类型,这个就不是重点了

  • 相关阅读:
    centos7.3部署memcached服务
    tomcat一闪而过,无法开启
    Windows系统因“CredSSP加密Oracle修正”无法远程连接
    猴子和打字机
    特修斯之船
    爱因斯坦的光线
    10个著名的思想实验(2)
    10个著名的思想实验1
    快速排序
    快速排序的c++实现
  • 原文地址:https://www.cnblogs.com/dragonfive/p/2909568.html
Copyright © 2020-2023  润新知