简体   繁体   English

C ++帮助在地图中查找最大值

[英]C++ Help finding the max value in a map

I've been doing a basic program to find the max, min, median, variance, mode etc. of a vector. 我一直在做基本程序来找到矢量的最大值,最小值,中值,方差,模式等。 Everything went fine until I got to the mode. 一切都很顺利,直到我进入模式。

The way I see it, I should be able to loop through the vector, and for each number that occurs I increment a key on the map. 我看到它的方式,我应该能够循环遍历向量,对于每个出现的数字,我在地图上增加一个键。 Finding the key with the highest value would then be the one that occured the most. 找到具有最高值的密钥将是发生最多的密钥。 Comparing to other keys would tell me if it's a single multiple or no mode answer. 与其他键相比,它会告诉我它是单个多重模式还是无模式答案。

Here's the chunk of code that's been causing me so much trouble. 这是导致我如此麻烦的代码块。

map<int,unsigned> frequencyCount;
// This is my attempt to increment the values
// of the map everytime one of the same numebers 
for(size_t i = 0; i < v.size(); ++i)
    frequencyCount[v[i]]++;

unsigned currentMax = 0;
unsigned checked = 0;
unsigned maax = 0;
for(auto it = frequencyCount.cbegin(); it != frequencyCount.cend(); ++it )
    //checked = it->second;
    if (it ->second > currentMax)
    {
        maax = it->first;
    }
    //if(it ->second > currentMax){
    //v = it->first

cout << " The highest value within the map is: " << maax << endl;

The entire program can be seen here. 整个程序可以在这里看到。 http://pastebin.com/MzPENmHp http://pastebin.com/MzPENmHp

You can use std::max_element to find the highest map value (the following code requires C++11): 您可以使用std::max_element查找最高的映射值(以下代码需要C ++ 11):

std::map<int, size_t> frequencyCount;
using pair_type = decltype(frequencyCount)::value_type;

for (auto i : v)
    frequencyCount[i]++;

auto pr = std::max_element
(
    std::begin(frequencyCount), std::end(frequencyCount),
    [] (const pair_type & p1, const pair_type & p2) {
        return p1.second < p2.second;
    }
);
std::cout << "A mode of the vector: " << pr->first << '\n';

You never changed currentMax in your code. 您从未在代码中更改currentMax

map<int,unsigned> frequencyCount;
for(size_t i = 0; i < v.size(); ++i)
    frequencyCount[v[i]]++;

unsigned currentMax = 0;
unsigned arg_max = 0;
for(auto it = frequencyCount.cbegin(); it != frequencyCount.cend(); ++it ) }
    if (it ->second > currentMax) {
        arg_max = it->first;
        currentMax = it->second;
    }
}
cout << "Value " << arg_max << " occurs " << currentMax << " times " << endl;

Another way to find the mode is to sort the vector and loop through it once, keeping track of the indices where the values change. 找到该模式的另一种方法是对向量​​进行排序并循环一次,跟踪值变化的索引。

Here's a templated function based on Rob's excellent answer above. 这是一个基于Rob上面的优秀答案的模板化函数。

template<typename KeyType, typename ValueType> 
std::pair<KeyType,ValueType> get_max( const std::map<KeyType,ValueType>& x ) {
  using pairtype=std::pair<KeyType,ValueType>; 
  return *std::max_element(x.begin(), x.end(), [] (const pairtype & p1, const pairtype & p2) {
        return p1.second < p2.second;
  }); 
}

Example: 例:

std::map<char,int> x = { { 'a',1 },{ 'b',2 },{'c',0}}; 
auto max=get_max(x);
std::cout << max.first << "=>" << max.second << std::endl; 

Outputs: b=>2 输出:b => 2

you are almost there: simply add currentMax = it->second; 你几乎就在那里:只需添加currentMax = it->second; after maax = it->first; maax = it->first;

but using a map to locate the max is overkill: simply scan the vector and store the index where you find higher numbers: very similar to what you already wrote, just simpler. 但使用地图来定位最大值是过度的:只需扫描向量并将索引存储在您找到更高数字的地方:与您已编写的内容非常相似,只是更简单。

As someone accustomed to using boost libraries, an alternative to using the anonymous function proposed by Rob is the following implementation of std::max_element: 作为习惯使用boost库的人,使用Rob提出的匿名函数的替代方法是std :: max_element的以下实现:

std::map< int, unsigned >::const_iterator found = 
        std::max_element( map.begin(), map.end(),
                         ( boost::bind(&std::map< int, unsigned >::value_type::second, _1) < 
                           boost::bind(&std::map< int, unsigned >::value_type::second, _2 ) ) );

We may reuse key or, value comparator objects as per requirements in place of comparator api, while fetching min/max/ranges over any STL iterator. 我们可以根据需要重用密钥或值比较器对象来代替比较器api,同时在任何STL迭代器上获取最小/最大/范围。

http://www.cplusplus.com/reference/map/multimap/key_comp/ http://www.cplusplus.com/reference/map/multimap/value_comp/ http://www.cplusplus.com/reference/map/multimap/key_comp/ http://www.cplusplus.com/reference/map/multimap/value_comp/

== ==

Example: 例:

// multimap::key_comp
#include <iostream>
#include <map>

int main ()
{
  std::multimap<char,int> mymultimap;

  std::multimap<char,int>::key_compare mycomp = mymultimap.key_comp();

  mymultimap.insert (std::make_pair('a',100));
  mymultimap.insert (std::make_pair('b',200));
  mymultimap.insert (std::make_pair('b',211));
  mymultimap.insert (std::make_pair('c',300));

  std::cout << "mymultimap contains:\n";

  char highest = mymultimap.rbegin()->first;     // key value of last element

  std::multimap<char,int>::iterator it = mymultimap.begin();
  do {
    std::cout << (*it).first << " => " << (*it).second << '\n';
  } while ( mycomp((*it++).first, highest) );

  std::cout << '\n';

  return 0;
}


Output:
mymultimap contains:
a => 100
b => 200
b => 211
c => 300

== ==

We can easily do this by using max_element() function. 我们可以使用max_element()函数轻松完成此操作。

Code Snippet : 代码片段:


#include <bits/stdc++.h>
using namespace std;

bool compare(const pair<int, int>&a, const pair<int, int>&b)
{
   return a.second<b.second;
}

int main(int argc, char const *argv[])
{
   int n, key, maxn;
   map<int,int> mp;

   cin>>n;

   for (int i=0; i<n; i++)
   {
     cin>>key;
     mp[key]++;
   }

   maxn = max_element(mp.begin(), mp.end(), compare)->second;

   cout<<maxn<<endl;

   return 0;
 }

You guys write too much. 你们写的太多了。 This can be done in few lines, here's a full working snippet: 这可以在几行中完成,这是一个完整的工作片段:

#include <iostream>
#include <algorithm>
#include <map>
int main() {
    std::map<char,int> x = { { 'a',1 },{ 'b',2 },{'c',0} };
    std::map<char,int>::iterator best
        = std::max_element(x.begin(),x.end(),[] (const std::pair<char,int>& a, const std::pair<char,int>& b)->bool{ return a.second < b.second; } );
    std::cout << best->first << " , " << best->second << "\n";
}

Beter use inner comparator map::value_comp(). Beter使用内部比较器map :: value_comp()。

For example: 例如:

#include <algorithm>
...
auto max = std::max_element(freq.begin(), freq.end(), freq.value_comp());
std::cout << max->first << "=>" << max->second << std::endl

will output: 将输出:

Key => Value

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM