2012-02-21 11 views
20

Zrobiłem podstawowy program, aby znaleźć maksimum, min, medianę, wariancję, tryb itd. Wektora. Wszystko poszło dobrze, aż dotarłem do trybu.C++ Pomoc w znalezieniu maksymalnej wartości na mapie

Sposób, w jaki to widzę, powinien być w stanie przechodzić przez wektor, a dla każdej liczby, która występuje, zwiększam klucz na mapie. Znalezienie klucza o najwyższej wartości byłoby tym, które wystąpiło najwięcej. W porównaniu do innych kluczy powiedziałbym mi, czy jest to odpowiedź pojedyncza czy wielokrotna.

Oto fragment kodu, który przysporzył mi tyle kłopotów.

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; 

Cały program można obejrzeć tutaj. http://pastebin.com/MzPENmHp

Odpowiedz

5

Nigdy nie zmieniono currentMax w kodzie.

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; 

Innym sposobem znalezienia trybu jest posortowanie wektora i przejście go raz, śledzenie indeksów, w których zmieniają się wartości.

+0

Dziękuję bardzo, pracował idealnie. – Sh0gun

+0

W przypadku dużej mapy powinno być szybciej używać funkcji członka mapy (może być połączone z wyszukiwaniem binarnym), std :: map :: upper_bound? –

2

jesteś prawie tam: wystarczy dodać currentMax = it->second; po maax = it->first;

ale przy użyciu mapy, aby zlokalizować max jest przesadą: po prostu zeskanować wektor i przechowywać indeks gdzie można znaleźć wyższe numery: bardzo podobny do tego, co już napisał, po prostu prostsze.

55

Można użyć std::max_element znaleźć najwyższą wartość mapa (poniższy kod C++ wymaga 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

Witam Rob, jak rozumiem funkcję? Czy to przeciążenie operatora []? [] (para stałych & p1, para stałych & p2) { powrót 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 w parze <..> jest const, tj. par ? – thomasa88

2

Jak ktoś przyzwyczajony do używania bibliotek Boost, alternatywę dla korzystania z anonimową funkcję proponowane przez Rob jest następującą implementacją 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 używa wewnętrznej mapy komparatora :: value_comp().

Na przykład:

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

wyjście wola:

Key => Value 
+7

Poniższy kod nie będzie działać. auto p = std :: max_element (freq.begin(), freq.end(), freq.value_comp()); Ponieważ> std :: map :: value_comp Zwraca obiekt porównawczy, którego można użyć do porównania > porównać dwa elementy, aby ustalić, czy klucz pierwszego z nich ma wartość > przed drugim. Więc p wskaże ostatni element na mapie. – ivan2kh

+2

To jest niewłaściwy komparator. Zobacz http://www.cplusplus.com/reference/map/map/value_comp/ – mmdanziger

+0

Zupełnie nie tak! Napraw lub usuń. – juanchopanza

1

Możemy ponownie wykorzystać klucz lub obiektów wartość porównawcze zgodnie z wymogami w miejscu komparatora API, podczas pobierania Min/Max/waha się dowolny iterator STL.

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

==

Przykład:

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

Oto matrycy funkcji oparty na doskonałą odpowiedź Roba powyżej.

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

przykład:

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

Wyjścia: B => 2

+0

Dzięki! Jest to odpowiedź przydatna dla osób, które szukają gotowej do użycia funkcji roboczej! – AlwaysLearning

0

Można to łatwo zrobić za pomocą max_element funkcję().

Code Snippet:


#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; 
} 
Powiązane problemy