2012-02-21 28 views
20

He estado haciendo un programa básico para encontrar el máximo, mínimo, mediana, varianza, modo, etc. de un vector. Todo fue bien hasta que llegué al modo.C++ Ayuda para encontrar el valor máximo en un mapa

De la forma en que lo veo, debería poder recorrer el vector, y para cada número que ocurre, aumento una tecla en el mapa. Encontrar la clave con el valor más alto sería la que más se produjo. Comparando con otras teclas me diría si se trata de una única respuesta de modo múltiple o ninguna.

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; 

Todo el programa se puede ver aquí. http://pastebin.com/MzPENmHp

Respuesta

5

Nunca ha cambiado currentMax en su 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 para ordenar el vector y el bucle a través de él una vez, hacer el seguimiento de los índices, donde cambian los valores.

+0

Muchas gracias, funcionó a la perfección. – Sh0gun

+0

Para un mapa grande, debería ser más rápido usar una función de miembro de mapa (quizás combinada con búsqueda binaria), std :: map :: upper_bound? –

2

que está casi allí: sólo tiene que añadir currentMax = it->second; después maax = it->first;

pero usando un mapa para localizar el máximo es una exageración: sólo tiene que escanear el vector y almacenar el índice donde se encuentran los números más altos: muy similar a lo que ya escribió, simplemente más simple.

55

Puede utilizar std::max_element para encontrar el valor más alto del mapa (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'; 
+0

Hola Rob, ¿cómo entender la función? ¿Es una sobrecarga de operador []? [] (const pair & p1, const pair & p2) { return p1.second thinkhy

+0

http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions http://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B_.28since_C.2B.2B11.29 –

+1

Shouldn 't int en el par <..> const, es decir, par ? – thomasa88

2

Como alguien acostumbrado a usar las bibliotecas alza, una alternativa al uso de la función anónima propuesto 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))); 
-1

Beter use inner comparator map :: 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 

salida voluntad:

Key => Value 
+7

El código siguiente no funcionará. auto p = std :: max_element (freq.begin(), freq.end(), freq.value_comp()); Dado que> std :: map :: value_comp devuelve un objeto de comparación que se puede usar para > compare dos elementos para ver si la clave del primero va > antes de la segunda. Entonces p señalará el último elemento en el mapa. – ivan2kh

+2

Ese es el elemento de comparación incorrecto. Ver http://www.cplusplus.com/reference/map/map/value_comp/ – mmdanziger

+0

¡Totalmente erróneo! Por favor, corrige o elimina. – juanchopanza

1

Podemos reutilizar tecla o, objetos comparador de valores según las necesidades en el lugar de api comparador, al recuperar min/max/rangos de más de cualquier iterador de 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 

==

3

Aquí hay una función de plantilla basado en excelente respuesta de Rob anteriormente.

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

+0

¡Gracias! ¡Esta es una respuesta que es útil para las personas que buscan una función de trabajo lista para usar! – AlwaysLearning

0

Podemos hacer esto fácilmente mediante el uso de 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; 
} 
Cuestiones relacionadas