• 搜狗面试的经典题(C++map按值排序,class struct的差别)


    一:起因

    (1)java  Map排序(key,value)。请看还有一篇博客 java Map排序 

    (2)c++ map排序(key,value),能够对c++ map和java Map进行对照:之中的一个,c++的map默认依照key值进行排序,并且就是map了;java Map HashMap是随

    的,不进行排序的。之二。c++声明对象直接Map map(^)的。不用= new的

    (3)c++ 按value值排序。map是不能直接排序的。它尽管也是一个数据集合,第一反应是利用stl中提供的sort算法实现,这个想法是好的,不幸的是。sort算法有个限制。利用sort算法仅仅能对序列容器进行排序,就是线性的(如vector,list。deque)map也是一个集合容器,可是它里面存储的元素是pair,它不是线性存储的(前面提过。像红黑树),所以利用sort不能直接和map结合进行排序。

    (4)  main函数中也能够实现函数重载,比如以下的 ostream& operator<<(ostream& out, const PAIR& p);还有就是定义的struct类(类似于class的)官方的说明见  (四)

    (5) 依照value值进行排序:把值定义为一个结构体,包含你原本的值元素,还有键的值。  这样当你要依照值排序的时候。把map的值也就是结构体放

    进vector中,剩下的依照你原来的值进行排序即可了。

    这样是不行的。由于key是确定的,而value是能够修改的     假设按value自己主动排序的话map会变得极不稳定。你想。假设每次改变value整个map都要又一次

    排序的话不是性能损耗会非常大吗?所以当初压根就没设计依照value排序的功能


    二:代码实现

    (1)先看pair类

    template <class T1, class T2> struct pair  
    {  
    	 typedef T1 first_type;  
    	 typedef T2 second_type;    
    	 T1 first;  
    	 T2 second;  
    	 pair() : first(T1()), second(T2()) {}  
    	pair(const T1& x, const T2& y) : first(x), second(y) {}  
    	template <class U, class V>  
        pair (const pair<U,V> &p) : first(p.first), second(p.second) { }  
    }
    
    pair也是一个模板类,这样就实现了良好的通用性。它仅有两个数据成员firstsecond,即 key value,并且

    (2)再看sort类

    template <class RandomAccessIterator>  
    void sort ( RandomAccessIterator first, RandomAccessIterator last );  
    	  
    template <class RandomAccessIterator, class Compare>  
    void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp ); 

    我们看到。令人兴奋的是,sort算法和map一样,也能够让我们指定元素间怎样进行比較,即指定Compare

    (3)完整代码

    #include<map>
    #include<string>
    #include<iostream>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    typedef pair<string, int> PAIR;
    // 原来还能够这种重载的(⊙o⊙)哦,长见识了
    ostream& operator<<(ostream& out, const PAIR& p)
    {
        return out << p.first << "	" << p.second;
    }
    template<class T1>
    struct compareByKeyLen
    {// 从短到长
        bool operator()(const T1 &s1,const T1 &s2)
        {
            return s1.length()<=s2.length()?true:false;// 记得有等号的哦,否则。长度相等的就舍去了
        }
    };
    template<class T1>
    struct compareByValue
    {
        bool operator()(const T1 &lhs, const T1 &rhs)
        {
            return lhs.second<=rhs.second ? true:false;
        }
    };
    
    int main()
    {
        //map<string, int> name_score_map;//字典的顺序,从小到大
        //默认的是map<string,int,less<string>>
    
        //map<string, int, greater<string> > name_score_map;// 注意> >有空格的,否则cin>>了;
        //字典的逆序,从大到小
    
        //map<string, int, compareByKeyLen<string> > name_score_map;
        // 自己写的compareByKeyLen<>结构体
    
        map<string, int> name_score_map;
    
        name_score_map["ZhaoBo2"] = 90;
        name_score_map["XuQingzhu"] = 79;
        name_score_map["LiBing"] = 92;
        name_score_map.insert(make_pair("ChiXiaotong",99));
        name_score_map.insert(make_pair("WangZhaoxian",86));
    
        vector<PAIR> name_score_vec(name_score_map.begin(),name_score_map.end());
        sort(name_score_vec.begin(),name_score_vec.end(),compareByValue<PAIR>());
        for(int i=0;i<name_score_vec.size();i++)
        {
            cout << name_score_vec[i] << endl;
        }
    //    for (map<string, int>::iterator iter = name_score_map.begin();
    //               iter != name_score_map.end();++iter)
    //    {
    //       cout << *iter << endl;
    //    }
        return 0;
    }
    
    (4)执行结果:



    三:按key值排序(c++ map 带有比較类的,这和java一样,java也带有类似的比較类)

    (1)compare类自定义

    比方。依照学生姓名的长短排序进行存储,那该怎么做呢?

    事实上非常easy,仅仅要我们自己写一个函数对象,实现想要的逻辑,定义map的时候把Compare指定为我们自己编写的这个就ok啦。

    template<class T1>
    struct compareByKeyLen
    {// 从短到长
        bool operator()(const T1 &s1,const T1 &s2)
        {
            return s1.length()<=s2.length()?

    true:false;// 记得有等号的哦,否则,长度相等的就舍去了 } };

    是不是非常easy!

    这里我们不用把它定义为模板。直接指定它的參数为string类型就能够了。

    (2)參考代码

    #include<map>
    #include<string>
    #include<iostream>
    using namespace std;
    
    typedef pair<string, int> PAIR;
    // 原来还能够这种重载的(⊙o⊙)哦,长见识了
    ostream& operator<<(ostream& out, const PAIR& p)
    {
        return out << p.first << "	" << p.second;
    }
    template<class T1>
    struct compareByKeyLen
    {// 从短到长
        bool operator()(const T1 &s1,const T1 &s2)
        {
            return s1.length()<=s2.length()?true:false;// 记得有等号的哦,否则,长度相等的就舍去了
        }
    };
    int main()
    {
        //map<string, int> name_score_map;//字典的顺序,从小到大
        //默认的是map<string,int,less<string>>
    
        //map<string, int, greater<string> > name_score_map;// 注意> >有空格的。否则cin>>了;
        //字典的逆序,从大到小
        map<string, int, compareByKeyLen > name_score_map;
        name_score_map["ZhaoBo"] = 90;
        name_score_map["XuQingzhu"] = 79;
        name_score_map["LiBing"] = 92;
        name_score_map.insert(make_pair("ChiXiaotong",99));
        name_score_map.insert(make_pair("WangZhaoxian",86));
        for (map<string, int>::iterator iter = name_score_map.begin();
                   iter != name_score_map.end();++iter)
        {
           cout << *iter << endl;
        }
        return 0;
    }
    

    (3)执行结果


    这一点有点类似javamap可是还是不一样的,感觉java倒是麻烦一些了。


    四:从语法上,在C++中(仅仅讨论C++中)。class和struct做类型定义时仅仅有两点差别

    从语法上,在C++中(仅仅讨论C++中)。

    class和struct做类型定义时仅仅有两点差别:

    (一)默认继承权限。假设不明白指定。来自class的继承依照private继承处理,来自struct的继承依照public继承处理;

    (二)成员的默认訪问权限。class的成员默认是private权限,struct默认是public权限。

    除了这两点,class和struct基本就是一个东西。语法上没有不论什么其他差别。


    不能由于学过C就总认为连C++中struct和class都差别非常大,以下列举的说明可能比較无聊,由于struct和class本来就是基本一样的东西,无需多说。但这些说

    明可能有助于澄清一些常见的关于struct和class的错误认识:

    (1)都能够有成员函数;包含各类构造函数,析构函数。重载的运算符,友元类。友元结构,友元函数。虚函数。纯虚函数,静态函数;

    (2)都能够有一大堆public/private/protected修饰符在里边;

    (3)尽管这样的风格不再被提倡,但语法上二者都能够使用大括号的方式初始化:Aa={1,2,3};无论A是个struct还是个class。前提是这个类/结构足够简单,比方全部的成员都是public的。全部的成员都是简单类型。没有显式声明的构造函数。

    (4)都能够进行复杂的继承甚至多重继承,一个struct能够继承自一个class,反之亦可。一个struct能够同一时候继承5个class和5个struct。尽管这样做不太好。

    (5)假设说class的设计须要注意OO的原则和风格。那么没不论什么理由说设计struct就不须要注意。


    (6)再次说明。以上全部说法都是指在C++语言中,至于在C里的情况,C里是根本没有“class”,而C的struct从根本上也仅仅是个包装数据的语法机制。
    最后。作为语言的两个keyword。除去定义类型时有上述差别之外。另外另一点点:“class”这个keyword还用于定义模板參数。就像“typename”。但keyword“struct”不用于定义模板參数。


  • 相关阅读:
    理解AI的角度
    如何提升分享信息的价值
    大数据和你想的不一样
    《卓有成效的程序员》笔记
    Mac下安装和使用GunPG(GPG)
    hive界面工具SQL Developer的安装;使用sql developer连接hive;使用sql developer连接mysql
    mac os安装jdk、卸载
    前端模板inspinia
    squirrelsql安装
    GOPATH设置
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7077761.html
Copyright © 2020-2023  润新知