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
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.
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';
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
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 ) ) );
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.
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
==
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;
}
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";
}