web-dev-qa-db-fra.com

Utiliser std :: max_element sur un vecteur <double>

J'essaie d'utiliser std::min_element et std::max_element pour retourner les éléments min et max dans un vecteur de doubles. Mon compilateur n'aime pas la façon dont je tente de les utiliser et je ne comprends pas le message d'erreur. Je pourrais bien sûr écrire ma propre procédure pour trouver le min/max, mais j'aimerais comprendre comment utiliser les fonctions.

#include <vector>
#include <algorithm>

using namespace std;

int main(int argc, char** argv) {

    double cLower, cUpper;
    vector<double> C;

    // code to insert values in C not shown here

    cLower = min_element(C.begin(), C.end());
    cUpper = max_element(C.begin(), C.end());

    return 0;
}

Voici l'erreur du compilateur:

../MIXD.cpp:84: error: cannot convert '__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >' to 'double' in assignment
../MIXD.cpp:85: error: cannot convert '__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >' to 'double' in assignment

Est-ce que quelqu'un pourrait expliquer ce que je fais mal?

72
synaptik

min_element et max_element renvoie des itérateurs, pas des valeurs. Donc vous avez besoin de *min_element... et *max_element....

105
David Schwartz

Comme d’autres l’ont dit, std::max_element() et std::min_element() retour itérateurs , qui doit être déréférencé pour obtenir la valeur.

L'avantage de renvoyer un itérateur (plutôt qu'une simple valeur) est qu'il vous permet de déterminer position du (premier) élément du conteneur avec la valeur maximale (ou minimale).

Par exemple (en utilisant C++ 11 par souci de brièveté):

#include <vector>
#include <algorithm>
#include <iostream>

int main()
{
    std::vector<double> v {1.0, 2.0, 3.0, 4.0, 5.0, 1.0, 2.0, 3.0, 4.0, 5.0};

    auto biggest = std::max_element(std::begin(v), std::end(v));
    std::cout << "Max element is " << *biggest
        << " at position " << std::distance(std::begin(v), biggest) << std::endl;

    auto smallest = std::min_element(std::begin(v), std::end(v));
    std::cout << "min element is " << *smallest
        << " at position " << std::distance(std::begin(v), smallest) << std::endl;
}

Cela donne:

Max element is 5 at position 4
min element is 1 at position 0

Remarque:

Utiliser std::minmax_element() comme suggéré dans les commentaires ci-dessus peut être plus rapide pour les grands ensembles de données, mais peut donner des résultats légèrement différents. Les valeurs pour mon exemple ci-dessus seraient les mêmes, mais la position de l'élément "max" serait 9 Depuis ...

Si plusieurs éléments sont équivalents au plus grand élément, l'itérateur du dernier élément est renvoyé.

55
Johnsyweb

min/max_element renvoie le itérateur à l'élément min/max, pas la valeur de l'élément min/max. Vous devez déréférencer l'itérateur pour obtenir la valeur et l'affecter à un double. C'est:

cLower = *min_element(C.begin(), C.end());
26
Cornstalks