【问题标题】:Finding the max value in a map查找地图中的最大值
【发布时间】:2012-03-11 08:57:07
【问题描述】:

我一直在做一个基本程序来查找向量的最大值、最小值、中值、方差、众数等。在我进入模式之前一切都很好。

按照我的看法,我应该能够循环遍历向量,并且对于出现的每个数字,我都会在地图上增加一个键。找到具有最高值的键将是出现次数最多的键。与其他键比较会告诉我它是单个多重还是无模式答案。

这是给我带来很多麻烦的代码块。

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;

整个程序可以在这里看到。 http://pastebin.com/MzPENmHp

【问题讨论】:

    标签: c++ dictionary vector max mode


    【解决方案1】:

    您可以使用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';
    

    【讨论】:

    【解决方案2】:

    这可以在几行内完成,这是一个完整的工作 sn-p:

    #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";
    }
    

    【讨论】:

    • 为什么每个人都使用 std:: 而不是使用命名空间?
    • 避免命名空间污染。污染可能是大型项目的真正障碍。甚至由于链接器混淆来自不同命名空间的相同类名而导致崩溃:gitlab.com/yade-dev/trunk/-/issues/57
    • 范围:std::ranges::max_element(x, [](std::pair&lt;char, int&gt; a, std::pair&lt;char, int&gt; b) { return a.second &lt; b.second; })
    【解决方案3】:

    您从未在代码中更改过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;
    

    另一种查找模式的方法是对向量​​进行排序并循环一次,跟踪值变化的索引。

    【讨论】:

    • 对于大地图,使用map成员函数(可能结合二分查找),std::map::upper_bound应该会更快?
    【解决方案4】:

    这是一个基于 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;
      }); 
    }
    

    例子:

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

    输出:b=>2

    【讨论】:

      【解决方案5】:

      我们可以根据要求重用键或值比较器对象来代替比较器 api,同时通过任何 STL 迭代器获取最小/最大/范围。

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

      ==

      例子:

      // 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
      

      ==

      【讨论】:

        【解决方案6】:

        你就快到了:只需在maax = it-&gt;first; 之后添加currentMax = it-&gt;second;

        但是使用地图来定位最大值是多余的:只需扫描向量并将索引存储在您找到更高数字的位置:与您已经编写的非常相似,只是更简单。

        【讨论】:

          【解决方案7】:

          我们可以通过使用 max_element() 函数轻松做到这一点。

          代码片段:


          #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;
           }
          

          【讨论】:

            【解决方案8】:

            作为习惯使用 Boost 库的人,使用匿名函数 proposed by 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 ) ) );
            

            【讨论】:

              【解决方案9】:

              最好使用内部比较器 map::value_comp()。

              例如:

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

              将输出:

              Key => Value
              

              【讨论】:

              • 下面的代码不起作用。自动 p = std::max_element(freq.begin(), freq.end(), freq.value_comp());由于 > std::map::value_comp 返回一个比较对象,该对象可用于 > 比较两个元素以获取第一个元素的键是否 > 第二个元素。所以 p 将指向 map 中的最后一个元素。
              • 那是错误的比较器。见cplusplus.com/reference/map/map/value_comp
              猜你喜欢
              • 2020-11-22
              • 2019-09-16
              • 2018-06-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多