zoukankan      html  css  js  c++  java
  • STL应用之set

    之前在解决一道算法题的时候,应用到set,特意对这个stl的容器类做了一些了解。在我的印象中,set就是一个元素不重复的集合,而事实上也正是这样的。无论从MSDN还是任何其它地方,都会告诉我们set的元素不可以重复。反之,只要元素不重复,就可以顺利的放入到set中。看起来这实在是再清楚不过了,但是仔细想一想的话,就会发现,话说只要不重复的元素就可以被放入到一个set中,但是什么样的元素是不重复的元素呢?或者说,什么样的元素是互不相同的呢?对于内置数据类型,也就是传说中的primary data type,像int 、 double、unsigned,甚至string,这些元素的“相同”非常容易理解,那么对于自定义类型呢?什么样的数据是相同的呢?什么样的数据又是不同的呢?

    在以前学习STL的时候,曾经学到过,如果要将自定义的类型放入到set中的话,就需要重载“<”符号,原因是set是一个有序的集合,集合会按照“<”比较的大小,默认按照从小到大的顺序排列。假设我现在设计如下类型:

    class MyType
    
    {
    
    public:
    
      int a, b, c;
    
    }

    这是,为了让MyType类型可以顺利的放进set中,我必须重载“<”,这时问题来了,要如何重载呢?这个类型有三个数据成员,我能不能要求按照a的大小排列,如果a相等的话就随便按照b或者c的大小排列呢?如果近实现按照a的大小排列的话,重载函数如下:

    bool operator<(const MyType& myType) const
    
    {
    
       return a<myType.a;
    
    }

    看起来简单明了,但是事实真的是这样吗?如果我声明一个set,并在其中放入MyType(1,2,3)、MyType(1,2,4)我能成功吗?实验了一下,结果如下:

    image

    测试时用的代码是这样的:

    #include<iostream>
    
    #include<set>
    
    using namespace std;
    
    
    
    class MyType
    
    {
    
    public:
    
      int a, b, c;
    
      MyType(int a, int b, int c):a(a), b(b), c(c){}
    
      bool operator<(const MyType& myType) const
    
      {
    
        return a<myType.a;
    
      }
    
    };
    
    int main()
    
    {
    
      set<MyType> se;
    
      MyType type1(1,2,3);
    
      MyType type2(1,2,4);
    
      se.insert(type1);
    
      se.insert(type2);
    
    
    
      cout<<"The set size:"<<se.size()<<endl;
    
      cout<<"Elements in the set as follows:"<<endl;
    
      for(set<MyType>::iterator it = se.begin(); it != se.end(); it++)
    
      {
    
        cout<<"("<<it->a<<", "<<it->b<<", "<<it->c<<") ";
    
      }
    
      cout<<endl;
    
      return 0;
    
    }

    结果很明显,当我已经把MyType(1,2,3)放到set中之后,就不能把MyType(1,2,4)放进去了。但是为什么呢?这两个对象看起来确实不一样啊!STL在比较是否相同的时候不是要比较每一个数据成员的吗?从上述的例子中,看到的确实不是这样的,STL不会自动的做任何比较,它仅对你说明过的动作干一些指定的活儿。在重载“<”的时候,当只指定众多数据成员中的一部分的时候,如果这部分都相同的话,set就认为是同一个元素了。就如上述所示一样,重载的时候仅作了a的比较,而没有说明如果a相同的话,是否对剩下的元素进行比较。这样一来,set认为MyType(1,2,3)和MyType(1,2,4)是一样的。要让set正确的进行大小的比较,针对自定义类型,就必须说明所有的数据成员的比较情况。如上述的例子的“<”重载,应该这样写:

    bool operator<(const MyType& myType) const
    
    {
    
      return a<myType.a?true:(b<myType.b?true:c<myType.c);
    
    }

    这样一来,就完全说明了每一个数据成员的比较关系,set就可以正常工作了。还是MyType(1,2,3)、MyType(1,2,4)两个元素,这回运行的结果如下:

    image

    运行代码为:

    #include<iostream>
    
    #include<set>
    
    using namespace std;
    
    
    
    class MyType
    
    {
    
    public:
    
      int a, b, c;
    
      MyType(int a, int b, int c):a(a), b(b), c(c){}
    
      bool operator<(const MyType& myType) const
    
      {
    
        return a<myType.a?true:(b<myType.b?true:c<myType.c);
    
      }
    
    };
    
    int main()
    
    {
    
      set<MyType> se;
    
      MyType type1(1,2,3);
    
      MyType type2(1,2,4);
    
      se.insert(type1);
    
      se.insert(type2);
    
    
    
      cout<<"The set size:"<<se.size()<<endl;
    
      cout<<"Elements in the set as follows:"<<endl;
    
      for(set<MyType>::iterator it = se.begin(); it != se.end(); it++)
    
      {
    
        cout<<"("<<it->a<<", "<<it->b<<", "<<it->c<<") ";
    
      }
    
      cout<<endl;
    
      return 0;
    
    }









  • 相关阅读:
    .NET Core+MySql+Nginx 容器化部署
    .NET Core容器化之多容器应用部署@Docker-Compose
    .NET Core容器化@Docker
    Hello Docker
    使用Bitbucket Pipeline进行.Net Core项目的自动构建、测试和部署
    一道面试题的思考
    ABP入门系列(21)——切换MySQL数据库
    爬取朋友圈,Get年度关键词
    一张图理清ASP.NET Core启动流程
    UnitOfWork知多少
  • 原文地址:https://www.cnblogs.com/huhu0013/p/4548341.html
Copyright © 2011-2022 走看看