搜狗面试的经典题(map按值排序)

一:起因

(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结合进行排序。

二:代码实现

(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也是一个模板类,这样就实现了良好的通用性。它仅有两个数据成员first
和second,即
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 << "\t" << 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类自己定义

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

其实很简单,只要我们自己写一个函数对象,实现想要的逻辑,定义map的时候把Compare指定为我们自己编写的这个就ok啦。

template<class T1>
struct compareByKeyLen
{// 从短到长
    bool operator()(const T1 &s1,const T1 &s2)
    {
        return s1.length()<=s2.length()?true:false;// 记得有等号的哦,否则,长度相等的就舍去了
    }
};

是不是很简单!这里我们不用把它定义为模板,直接指定它的参数为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 << "\t" << 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)运行结果

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

时间: 2024-11-05 15:49:18

搜狗面试的经典题(map按值排序)的相关文章

SQL面试笔试经典题(Part 1)

本文是在Cat Qi的原贴的基础之上,经本人逐题分别在MySql数据库中实现的笔记,持续更新... 参考原贴:http://www.cnblogs.com/qixuejia/p/3637735.html 01 表结构 Student(Sno,Sname,Sage,Ssex) 学生表  Course(Cno,Cname,Tno) 课程表  SC(Sno,Cno,score) 成绩表  Teacher(Tno,Tname) 教师表 02 建表及插入测试数据 (1) 建表: 1 DROP TABLE

JAVA面试/笔试经典题

1.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 对于short s1 = 1; s1 = s1 + 1; 由于s1+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误.对于short s1 = 1; s1 += 1;由于 += 是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译. 2.是否可以从一个static方法内部发出对非s

计蒜客-题库-三值排序

题目 排序是一种很频繁的计算任务.一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌排序的时候.在这个任务中可能的值只有三种1,2和3.我们用交换的方法把他排成升序的. 写一个程序计算出,计算出的一个包括1.2.3三种值的数字序列,排成升序所需的最少交换次数. 输入第1行为类别的数量N(1≤N≤1000) 输入第2行到第N+1行,每行包括一个数字(1或2或3). 输出包含一行,为排成升序所需的最少交换次数. 样例输入 9 2 2 1 3 3 3 2 3 1 样例输出 4 思路 对于排好序的1.

map按照值排序

1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 map<int,int/*,greater<int>*/>mp; 6 //Tip: map按照key从大到小排序 map<int,int,greater<int>> mp; 7 8 bool cmp(const pair<int,int> &a, const pair<int,int> &b){ 9

hdu 1541/poj 2352:Stars(树状数组,经典题)

Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4052    Accepted Submission(s): 1592 Problem Description Astronomers often examine star maps where stars are represented by points on a plan

poj 2182 Lost Cows(线段树经典题)

题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9152   Accepted: 5879 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, th

LeetCode面试常见100题( TOP 100 Liked Questions)

LeetCode面试常见100题( TOP 100 Liked Questions) 置顶 2018年07月16日 11:25:22 lanyu_01 阅读数 9704更多 分类专栏: 面试编程题真题合集 常见算法问题 LeetCode试题 LeetCode常见试题 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/lanyu_01/article/details/81062232 这篇文章

hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割

题意:方格取数,如果取了相邻的数,那么要付出一定代价.(代价为2*(X&Y))(开始用费用流,敲升级版3820,跪...) 建图:  对于相邻问题,经典方法:奇偶建立二分图.对于相邻两点连边2*(X&Y),源->X连边,Y->汇连边,权值w为点权. ans=总点权-最小割:如果割边是源->X,表示x不要选(是割边,必然价值在路径上最小),若割边是Y-汇点,同理:若割边是X->Y,则表示选Y点且选X点, 割为w( 2*(X&Y) ). 自己的确还没有理解其本质

POJ 2411 &amp;&amp; HDU 1400 Mondriaan&#39;s Dream (状压dp 经典题)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12341   Accepted: 7204 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series