web-dev-qa-db-fra.com

Aide C++ pour trouver la valeur maximale dans une carte

Je fais un programme de base pour trouver le maximum, le minimum, la médiane, la variance, le mode, etc. d'un vecteur. Tout s'est bien passé jusqu'à ce que je sois au mode.

De la façon dont je le vois, je devrais pouvoir parcourir le vecteur en boucle et, pour chaque nombre qui se produit, j'incrémente une clé sur la carte. Trouver la clé avec la valeur la plus élevée serait alors celle qui se produirait le plus. La comparaison avec d'autres touches me dirait s'il s'agit d'une réponse unique en mode multiple ou non. 

Voici le morceau de code qui me cause tant de problèmes. 

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;

Le programme complet peut être vu ici. http://Pastebin.com/MzPENmHp

30
Sh0gun

Vous n'avez jamais changé currentMax dans votre code.

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;

Une autre façon de trouver le mode consiste à trier le vecteur et à le parcourir une fois, en gardant une trace des index où les valeurs changent.

7
YXD

Vous pouvez utiliser std::max_element pour trouver la valeur de carte la plus élevée (le code suivant nécessite 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';
72
Robᵩ

Voici une fonction basée sur un modèle basée sur l'excellente réponse de Rob ci-dessus. 

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

Exemple:

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

Sorties: b => 2

6
daknowles

En tant que personne habituée à utiliser les bibliothèques boost, une alternative à la fonction anonyme proposée par Rob est la mise en oeuvre suivante de 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 ) ) );
2
dr_g

vous y êtes presque: ajoutez simplement currentMax = it->second; après maax = it->first;

mais utiliser une carte pour localiser le maximum, c'est exagéré: balayez simplement le vecteur et stockez l'index dans lequel vous trouvez des nombres plus élevés: très similaire à ce que vous avez déjà écrit, simplement.

2
CapelliC

Nous pouvons réutiliser des objets de clé ou de comparateur de valeurs selon les exigences à la place de l’API du comparateur, tout en recherchant des valeurs min/max/sur un itérateur STL.

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

==

Exemple:

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

==

1
mav_2k

Nous pouvons facilement le faire en utilisant la fonction max_element ().

Extrait de code :


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

Vous écrivez trop. Cela peut être fait en quelques lignes, voici un extrait de travail complet:

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