标签:
对map的value进行排序的方法,注意思路,以及CMPBYVALUE的用法
<h1 class="title" style="margin: 10px 0px; font-family: 'lucida grande', 'lucida sans unicode', lucida, helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 1.5; color: rgb(85, 85, 85); text-rendering: optimizelegibility; font-size: 32px; word-break: break-all;">map按键排序和按值排序</h1><div class="show-content" style="color: rgb(47, 47, 47); font-size: 16px; line-height: 1.7; font-family: 'lucida grande', 'lucida sans unicode', lucida, helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;"><p style="margin-top: 0px; margin-bottom: 25px; text-align: justify; word-break: break-word;">前几天做了一个关于字符串的题,题目要求寻找一个字符串中出现最多的子串是哪一个,没想到什么很有技巧的想法,于是就打算遍历所有的子串,利用一个map实现,其键值为对应的子串,value为子串出现的个数,遍历玩所有的子串后,只要寻找最大的value的键值就可以了,这里就想到一个问题,map一般是按键排序,能否按value排序?</p><p style="margin-top: 0px; margin-bottom: 25px; text-align: justify; word-break: break-word;">首先给出上述题目的一个解法,然后再继续讨论:map按键排序和按值排序的问题。如下所示,map查询采用find不要直接查询(find要是没找到则返回MAP.end()),否则会将map中不存在的键值直接插入。</p><pre class="hljs cpp" style="padding: 9.5px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; color: rgb(101, 123, 131); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 20px; line-height: 20px; word-break: break-all; word-wrap: normal; background-color: rgb(253, 246, 227); border: 1px solid rgba(0, 0, 0, 0.14902); overflow: auto;"><code class="cpp" style="padding: 0px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; background-color: transparent; border: none;"><span class="hljs-function"><span class="hljs-keyword" style="color: rgb(133, 153, 0);">void</span> <span class="hljs-title" style="color: rgb(38, 139, 210);">substrCount</span><span class="hljs-params">(<span class="hljs-built_in" style="color: rgb(38, 139, 210);">string</span> str)</span> </span>{ <span class="hljs-built_in" style="color: rgb(38, 139, 210);">map</span><<span class="hljs-built_in" style="color: rgb(38, 139, 210);">string</span>,<span class="hljs-keyword" style="color: rgb(133, 153, 0);">int</span>> substr; <span class="hljs-built_in" style="color: rgb(38, 139, 210);">string</span> subs; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">for</span>(<span class="hljs-keyword" style="color: rgb(133, 153, 0);">int</span> i =<span class="hljs-number" style="color: rgb(42, 161, 152);">1</span>; i<str.size();i++) <span class="hljs-keyword" style="color: rgb(133, 153, 0);">for</span>(<span class="hljs-keyword" style="color: rgb(133, 153, 0);">int</span> j =<span class="hljs-number" style="color: rgb(42, 161, 152);">0</span>; j<=str.size()-i;j++) { subs = str.substr(j,i); <span class="hljs-comment" style="color: rgb(147, 161, 161);">//遍历每一个子串</span> <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span>(substr.find(subs)==substr.end()) <span class="hljs-comment" style="color: rgb(147, 161, 161);">//判断map中是否存在,存在则+1,不存在则插入</span> substr[subs] = <span class="hljs-number" style="color: rgb(42, 161, 152);">1</span>; <span class="hljs-keyword" style="color: rgb(133, 153, 0);">else</span> substr[subs] = substr[subs]+<span class="hljs-number" style="color: rgb(42, 161, 152);">1</span>; } pair<<span class="hljs-built_in" style="color: rgb(38, 139, 210);">string</span>, <span class="hljs-keyword" style="color: rgb(133, 153, 0);">int</span>> maxpair = *(substr.begin()); <span class="hljs-comment" style="color: rgb(147, 161, 161);">//寻找出现次数最多的子串</span> <span class="hljs-built_in" style="color: rgb(38, 139, 210);">map</span><<span class="hljs-built_in" style="color: rgb(38, 139, 210);">string</span>,<span class="hljs-keyword" style="color: rgb(133, 153, 0);">int</span>>::iterator it = substr.begin(); <span class="hljs-keyword" style="color: rgb(133, 153, 0);">while</span>(it!=substr.end()) { <span class="hljs-keyword" style="color: rgb(133, 153, 0);">if</span>(it->second >maxpair.second ) maxpair = *it; } <span class="hljs-built_in" style="color: rgb(38, 139, 210);">cout</span><<maxpair.first<<endl; <span class="hljs-built_in" style="color: rgb(38, 139, 210);">cout</span><<maxpair.second<<endl; }</code>
map按键排序和按值排序的问题内容来自C++ STL中Map的按Key排序和按Value排序
template < class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key,T> > > class map;
其中第三、四个均包含默认参数,可以不指定。我们可以通过指定Compare类来指定排序的顺序。其中less<Key>是stl里面的一个函数对象(即调用操作符的类,其对象常称为函数对象(function object),它们是行为类似函数的对象,表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个 类,其实质是对operator()操作符的重载)其具体定义如下
template <class T> struct less : binary_function <T,T,bool> {
bool operator() (const T& x, const T& y) const
{return x<y;}
};
它是一个带模板的struct,里面仅仅对()运算符进行了重载。与less相对的有greater,定义如下
template <class T> struct greater : binary_function <T,T,bool> {
bool operator() (const T& x, const T& y) const
{return x>y;}
};
map<string,int,greater<string> >
或者定义自己的比较类comLen如下
struct comLen{
bool operator(const string &lhs, const string &rhs)
{return lhs.length()<rhs.length();}
}
map<string,int,comLen> LenLessMap;
map是元素为pair,其已实现<操作符的重载
template<class T1, class T2>
inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y)
{ return x.first < y.first || (!(y.first < x.first) && x.second < y.second); }
template <class RandomAccessIterator>
void sort ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
与map一样均可以指定比较的类。可以定义如下的比较的类或者对象
class combyValue
{
bool operator()(pair<string,int> &lhs,pair<string,int> &rhs)
{return lhs.second<rhs.second;}
}
map<string,int> m;
元素插入过程
vector<pair<string,int> > vec(m.begin(),m.end());
sort(vec.begin(),vec.end(),combyValue);
因此最开始的那道题如果需要排序的话可以按如下方式写
struct CmpByValue {
bool operator()(const pair<string,int> & lhs, const pair<string,int> & rhs)
{return lhs.second > rhs.second;}
};
void substrcount(string str)
{
map<string,int> substr;
string subs;
for(int i =1; i<str.size();i++)
for(int j =0; j<=str.size()-i;j++)
{
subs = str.substr(j,i);
if(substr.find(subs)==substr.end())
substr[subs] = 1;
else
substr[subs] = substr[subs]+1;
}
vector<pair<string,int>> counts(substr.begin(),substr.end());
sort(counts.begin(),counts.end(),CmpByValue());
cout<<counts.begin()->first<<endl;
cout<<counts.begin()->second<<endl;
}
我自己的代码实现!
static map<int ,int> mapwords; void main() { vector<string> info; bool MeorCh=true; //设置统计公式还是中文 FILE *fpstatic = fopen("count.txt","w"); char *dat="answer"; const char *QuestionId = "045176078D274A3A9CC7E5437FCFB95B" ; char *title="liang"; int size=111; //size = ReadFile("E:\\梁栋凯\\countstestdata\\045176078D274A3A9CC7E5437FCFB95B.dat",dat); //cout<<"ReadFile: "<<size<<endl; //size = ReadAnswerFile("E:\\梁栋凯\\countstestdata",QuestionId,title,info) ; // cout<<"ReadAnswerFile: "<<size; //int flag=ReadAnswerFile("E:\\梁栋凯\\countstestdata",QuestionId , &answer); //if(flag==0)cout<<"读取成功!" <<endl; //连续读取文件 vector<string> files; // const char *pTag = ".dat"; getFiles("E:\\梁栋凯\\countstestdata\\", files ); std::string datFileName; //string dir=files[0].substr(0,25); //string ID=files[0].substr(25,files[0].size()-29); int i=0; if(i<12220) { QUESTIONANSWER answer1; for(i=0;i<files.size()&&i<=12220;i++) { string temp=files[i]; string dir=files[i].substr(0,25); //路径长度+4 string ID=files[i].substr(25,files[i].size()-29); const char *sdir=dir.c_str(); const char *AnswerID=ID.c_str(); int flag=ReadAnswerFile("E:\\梁栋凯\\countstestdata\\", AnswerID, &answer1); if(flag==0)cout<<"读取"<<i<<"文件成功!" <<endl; } int flag1 = CountWords(answer1,MeorCh); } if(i>12220&&i<files.size()) { QUESTIONANSWER answer2; for(;i<files.size();i++) { string temp=files[i]; string dir=files[i].substr(0,25); //路径长度+4 string ID=files[i].substr(25,files[i].size()-29); const char *sdir=dir.c_str(); const char *AnswerID=ID.c_str(); int flag=ReadAnswerFile("E:\\梁栋凯\\countstestdata\\", AnswerID, &answer2); if(flag==0)cout<<"读取"<<i<<"文件成功!" <<endl; } int flag1 = CountWords(answer2,MeorCh); } ////统计字符出现的频率 //int flag1 = CountWords(answer,MeorCh); struct CmpByValue { bool operator()(const pair<int,int> & lhs, const pair<int,int> & rhs) {return lhs.second > rhs.second;} }; //转存map到vector vector<pair<int,int> > vec(mapwords.begin() , mapwords.end()); //排序 cout<<"sort vector start!"<<endl; sort(vec.begin(),vec.end(),CmpByValue()); for(int i=0; i<vec.size();i++) { fprintf(fpstatic, "%d, %d\n", vec[i].first,vec[i].second ); cout<<vec[i].first<<", "<<vec[i].second<<endl; } // // //map<int, int>::iterator iter ; // for(iter = mapwords.begin(); iter != mapwords.end(); ++iter) // { // fprintf(fpstatic, "%d, %d\n", iter->first,iter->second ); // cout << iter->first << " " // << iter->second << endl; // } } int CountWords(QUESTIONANSWER answer , bool MeorCh ) { bool MethorCh = MeorCh; if(MethorCh){ for(unsigned int i = 0; i < answer.gramMe.size(); i++) { mapwords[answer.gramMe[i]]++; } } else { for(unsigned int i = 0; i < answer.gramCh.size(); i++) { mapwords[answer.gramCh[i]]++; } } return 1; }
标签:
原文地址:http://blog.csdn.net/u010159842/article/details/51396238