una - C++ Ayuda para encontrar el valor máximo en un mapa
numero mayor de un arreglo c++ (8)
He estado haciendo un programa básico para encontrar el máximo, el mínimo, la mediana, la varianza, el modo, etc. de un vector. Todo fue bien hasta que llegué al modo.
De la forma en que lo veo, debería poder recorrer el vector en bucle y, para cada número que ocurra, incremento una tecla en el mapa. Encontrar la clave con el valor más alto sería la que más ocurriera. Compararlo con otras teclas me diría si se trata de una única respuesta múltiple o no.
Aquí está el trozo de código que me ha estado causando tantos problemas.
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;
El programa completo se puede ver aquí. http://pastebin.com/MzPENmHp
Aquí hay una función basada en la plantilla basada en la excelente respuesta de 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;
});
}
Ejemplo:
std::map<char,int> x = { { ''a'',1 },{ ''b'',2 },{''c'',0}};
auto max=get_max(x);
std::cout << max.first << "=>" << max.second << std::endl;
Salidas: b => 2
Beter utiliza el mapa comparador interno :: value_comp ().
Por ejemplo:
#include <algorithm>
...
auto max = std::max_element(freq.begin(), freq.end(), freq.value_comp());
std::cout << max->first << "=>" << max->second << std::endl
saldrá:
Key => Value
Como alguien acostumbrado a usar las bibliotecas boost, una alternativa a usar la función anónima propuesta por Rob es la siguiente implementación 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 ) ) );
Nunca has cambiado currentMax
en tu código.
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;
Otra forma de encontrar el modo es ordenar el vector y recorrerlo una vez, haciendo un seguimiento de los índices donde cambian los valores.
Podemos hacerlo fácilmente usando la función max_element ().
Fragmento de código :
#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;
}
Podemos reutilizar los objetos clave o de valor de comparador según los requisitos en lugar de la API del comparador, mientras obtenemos min / max / rangos sobre cualquier iterador STL.
http://www.cplusplus.com/reference/map/multimap/key_comp/ http://www.cplusplus.com/reference/map/multimap/value_comp/
==
Ejemplo:
// 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
==
Puede usar std::max_element
para encontrar el valor de mapa más alto (el siguiente código requiere 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'';
casi has currentMax = it->second;
: simplemente agrega currentMax = it->second;
después de maax = it->first;
pero usar un mapa para localizar el máximo es excesivo: simplemente escanee el vector y almacene el índice donde encuentre números más altos: muy similar a lo que ya escribió, solo que más simple.