209

How can I get the maximum or minimum value in a vector in C++?

And am I wrong in assuming it would be more or less the same with an array?

I need an iterator, right? I tried it with max_element, but I kept getting an error.

vector<int>::const_iterator it;
it = max_element(cloud.begin(), cloud.end());
error: request for member ‘begin’ in ‘cloud’, which is of non-class type ‘int [10]’
bob blob
  • 2,191
  • 3
  • 15
  • 6
  • 3
    Looks like `cloud` isn't an STL container, but rather an `int[10]`. Basically, `cloud` doesn't have a member `.begin()`. Might want to get a basic C++ book unless you're only doing this one thing. – Chris A. Mar 26 '12 at 15:20
  • 1
    Some more code might be useful as well. Where is the definition of cloud? – Tim Mar 26 '12 at 15:26
  • 13
    @bobblob: and yet the compiler error you posted said that "cloud is of non-class type `int[10]`". How can it be a vector then? – jalf Mar 26 '12 at 15:47
  • It's confusing for readers that the title and the tag say `vector`, but actually it's not, as others commented above. At least you could read these comments... – starriet Aug 19 '22 at 12:37

10 Answers10

173

Using C++11/C++0x compile flags, you can

auto it = max_element(std::begin(cloud), std::end(cloud)); // C++11

Otherwise, write your own:

template <typename T, size_t N> const T* mybegin(const T (&a)[N]) { return a; }
template <typename T, size_t N> const T* myend  (const T (&a)[N]) { return a+N; }

See it live at http://ideone.com/aDkhW:

#include <iostream>
#include <algorithm>

template <typename T, size_t N> const T* mybegin(const T (&a)[N]) { return a; }
template <typename T, size_t N> const T* myend  (const T (&a)[N]) { return a+N; }

int main()
{
    const int cloud[] = { 1,2,3,4,-7,999,5,6 };

    std::cout << *std::max_element(mybegin(cloud), myend(cloud)) << '\n';
    std::cout << *std::min_element(mybegin(cloud), myend(cloud)) << '\n';
}

Oh, and use std::minmax_element(...) if you need both at once :/

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Hi, do you know is it possible to apply it to dimension array or vector? – Charles Chow Aug 13 '14 at 21:58
  • 4
    Yes you can. The standard library algorithms have been designed to generically work on iterators. Pointers are iterators too. – sehe Aug 14 '14 at 09:48
  • Don't forget to include to use max_element. – gordon_freeman May 26 '22 at 14:42
  • Is there any advantage of `max_element(std::begin(cloud), std::end(cloud))` over `max_element(cloud.begin(), cloud.end());`? – starriet Aug 19 '22 at 08:36
  • 1
    @starriet Only that it supports more than standard containers that have `begin()`/`end()` member functions. That was the exact topic of the original question, as it was using a C-style array, which works with `std::begin(arr)` but not `arr.begin()`. – sehe Aug 19 '22 at 09:10
169

If you want to use the function std::max_element(), the way you have to do it is:

double max = *max_element(vector.begin(), vector.end());
cout<<"Max value: "<<max<<endl;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
26

Let,

 #include <vector>

 vector<int> v {1, 2, 3, -1, -2, -3};

If the vector is sorted in ascending or descending order then you can find it with complexity O(1).

For a vector of ascending order the first element is the smallest element, you can get it by v[0] (0 based indexing) and last element is the largest element, you can get it by v[sizeOfVector-1].

If the vector is sorted in descending order then the last element is the smallest element,you can get it by v[sizeOfVector-1] and first element is the largest element, you can get it by v[0].

If the vector is not sorted then you have to iterate over the vector to get the smallest/largest element.In this case time complexity is O(n), here n is the size of vector.

int smallest_element = v[0]; //let, first element is the smallest one
int largest_element = v[0]; //also let, first element is the biggest one
for(int i = 1; i < v.size(); i++)  //start iterating from the second element
{
    if(v[i] < smallest_element)
    {
       smallest_element = v[i];
    }
    if(v[i] > largest_element)
    {
       largest_element = v[i];
    }
}

You can use iterator,

for (vector<int>:: iterator it = v.begin(); it != v.end(); it++)
{
    if(*it < smallest_element) //used *it (with asterisk), because it's an iterator
    {
      smallest_element = *it;
    }
    if(*it > largest_element)
    {
      largest_element = *it;
    }
}

You can calculate it in input section (when you have to find smallest or largest element from a given vector)

int smallest_element, largest_element, value;
vector <int> v;
int n;//n is the number of elements to enter
cin >> n;
for(int i = 0;i<n;i++)
{
    cin>>value;
    if(i==0)
    {
        smallest_element= value; //smallest_element=v[0];
        largest_element= value; //also, largest_element = v[0]
    }

    if(value<smallest_element and i>0)
    {
        smallest_element = value;
    }

    if(value>largest_element and i>0)
    {
        largest_element = value;
    }
    v.push_back(value);
}

Also you can get smallest/largest element by built in functions

#include<algorithm>

int smallest_element = *min_element(v.begin(),v.end());

int largest_element  = *max_element(v.begin(),v.end());

You can get smallest/largest element of any range by using this functions. such as,

vector<int> v {1,2,3,-1,-2,-3};

cout << *min_element(v.begin(), v.begin() + 3); //this will print 1,smallest element of first three elements

cout << *max_element(v.begin(), v.begin() + 3); //largest element of first three elements

cout << *min_element(v.begin() + 2, v.begin() + 5); // -2, smallest element between third and fifth element (inclusive)

cout << *max_element(v.begin() + 2, v.begin()+5); //largest element between third and first element (inclusive)

I have used asterisk (*), before min_element()/max_element() functions. Because both of them return iterator. All codes are in c++.

Piyush Chauhan
  • 797
  • 1
  • 7
  • 20
Taohidul Islam
  • 5,246
  • 3
  • 26
  • 39
  • 2
    `min_element` and `max_element` return an **iterator**, not a pointer. However, to be technically correct a pointer is a subset of an iterator. See: https://stackoverflow.com/questions/2728190/how-are-iterators-and-pointers-related – rayryeng Oct 19 '17 at 07:14
18

You can print it directly using the max_element or min_element function.

For example:

cout << *max_element(v.begin(), v.end());

cout << *min_element(v.begin(), v.end());
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kishy Nivas
  • 663
  • 8
  • 21
12

Assuming cloud is int cloud[10] you can do it like this: int *p = max_element(cloud, cloud + 10);

Asha
  • 11,002
  • 6
  • 44
  • 66
4

In C++11, you can use some function like that:

int maxAt(std::vector<int>& vector_name) {
    int max = INT_MIN;
    for (auto val : vector_name) {
         if (max < val) max = val;
    }
    return max;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
2

You can use max_element to get the maximum value in vector. The max_element returns an iterator to largest value in the range, or last if the range is empty. As an iterator is like pointers (or you can say pointer is a form of iterator), you can use a * before it to get the value. So as per the problem you can get the maximum element in an vector as:

int max=*max_element(cloud.begin(), cloud.end());

It will give you the maximum element in your vector "cloud". Hope it helps.

Prashant Shubham
  • 456
  • 8
  • 20
2

Answer on the behalf of the author

for (unsigned int i = 0; i < cdf.size(); i++)
  if (cdf[i] < cdfMin)
    cdfMin = cdf[i];

where cdf is a vector.

2

If you want to use an iterator, you can do a placement-new with an array.

std::array<int, 10> icloud = new (cloud) std::array<int,10>;

Note the lack of a () at the end, that is important. This creates an array class that uses that memory as its storage, and has STL features like iterators.

(This is C++ TR1/C++11 by the way)

malat
  • 12,152
  • 13
  • 89
  • 158
std''OrgnlDave
  • 3,912
  • 1
  • 25
  • 34
  • `new` returns a pointer, not a value -- so `std;:array icloud = new ...` is a compilation error. Also once you invoke `new` of any kind (placement or otherwise) without initializing values, inspecting those values is undefined-behavior. Even though this is over top of an array of values of the same size, reading those values violates the standard, and the compiler is free to treat this code as invalid (which may optimize it away, remove it, etc) – Human-Compiler Feb 15 '22 at 22:00
1

Just this:

// assuming "cloud" is:
// int cloud[10]; 
// or any other fixed size

#define countof(x) (sizeof(x)/sizeof((x)[0]))

int* pMax = std::max_element(cloud, cloud + countof(cloud));
ivan.ukr
  • 2,853
  • 1
  • 23
  • 41
  • Why use macros? There's no reason for that! The error starts with `int cloud[10];` and it is the use of magic numbers. – Ulrich Eckhardt Dec 01 '18 at 20:48
  • 1
    Because from error message it is clear that he has not vector but normal array. And you have to count its length somehow, to avoid using hardcoded magic numbers. He may change length in future, but code for finding maximum this way will be the same. – ivan.ukr Dec 07 '18 at 10:53
  • Sorry, that didn't come across correctly. Your solution is correct, but bad. The reason is that it assumes use of magic numbers, which does not follow from the error message. It then continues with the use of macros, which are always a code smell. – Ulrich Eckhardt Dec 17 '18 at 21:27
  • In theory the macro can be expanded into the code, but I'd prefer to keep it as sort of rarely "useful" macros. Moreover, some vendors even do it OOB. For example, Visial C++ provides OOB "_countof" simular to above. If you know how to do the same using metaprogramming, but same short and elegant, please post your code example. – ivan.ukr Jun 16 '21 at 18:35