#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.小结一下,两个重点都是关于操作符的重载的 当时如果元素类型是基本类型,这个就不是重点了