97

How to use standard template library std::sort() to sort an array declared as int v[2000];

Does C++ provide some function that can get the begin and end index of an array?

Varaquilex
  • 3,447
  • 7
  • 40
  • 60

14 Answers14

118

In C++0x/11 we get std::begin and std::end which are overloaded for arrays:

#include <algorithm>

int main(){
  int v[2000];
  std::sort(std::begin(v), std::end(v));
}

If you don't have access to C++0x, it isn't hard to write them yourself:

// for container with nested typedefs, non-const version
template<class Cont>
typename Cont::iterator begin(Cont& c){
  return c.begin();
}

template<class Cont>
typename Cont::iterator end(Cont& c){
  return c.end();
}

// const version
template<class Cont>
typename Cont::const_iterator begin(Cont const& c){
  return c.begin();
}

template<class Cont>
typename Cont::const_iterator end(Cont const& c){
  return c.end();
}

// overloads for C style arrays
template<class T, std::size_t N>
T* begin(T (&arr)[N]){
  return &arr[0];
}

template<class T, std::size_t N>
T* end(T (&arr)[N]){
  return arr + N;
}
Xeo
  • 129,499
  • 52
  • 291
  • 397
  • 12
    Are `std::begin()` and `std::end()` C++1x additions? They're very nice -- should have been this way from the outset, it would have made a lot of algorithms more generic! – j_random_hacker May 05 '11 at 12:08
  • 10
    `std::begin()` and `std::end()` aren't a part of the current C++ Standard, but you can use `boost::begin()` and `boost::end()`. – Kirill V. Lyadvinsky May 05 '11 at 12:12
  • I believe they are C++98/03, but I'm on my iPod right now and I can't remember in which header they reside... Edit: Seems I'm worng, but it isn't hard to write those yourself. Gonna edit... – Xeo May 05 '11 at 12:13
  • @j_random_hacker, new to me too. Most google hits for std::begin/end point back to SO, e.g.: http://stackoverflow.com/questions/2648878/range-based-for-statement-definition-redundancy – luke May 05 '11 at 12:13
  • 1
    Edited accordingly to the comments. – Xeo May 05 '11 at 12:24
  • 2
    Just a reminder: long before they were to proposed for C++11, most of us had such a `begin` and `end` function in our personal tool kits. Before C++11, however, they had a serios disadvantage: they didn't result in an integral constant expression. So depending on the specific needs, we'd use them, or a macro which did the division of the two `sizeof`. – James Kanze May 05 '11 at 12:56
  • @James: Another important factor in C++11 is `decltype`. That way, you only need one template each for `begin` and `end` to support any range that has these member functions. – Xeo May 05 '11 at 13:10
  • 1
    @Xeo I'm not sure I understand what you're saying. `decltype` certainly simplifies certain uses, but I don't see what it has to do with the free `begin` and `end` functions. (And you really should have two each of them, one for C style arrays, and another for containers, with automatic discrimination, so you can use them in templates, without knowing whether the type is a container or a C style array.) – James Kanze May 05 '11 at 13:27
  • 1
    @James: D'oh, disregard that comment. I totally forgot about the nested typedefs in the STL container... Added the simple templates now. :) – Xeo May 05 '11 at 13:34
  • @Xeo Is there any particular reason you wrote `&arr[0]` instead of `arr`? Is not the name of an array synonymous with the address of the 0th element of an array? This is in regards to your begin overload for C style arrays. – ArtOfWarfare Mar 10 '13 at 20:49
  • @ArtOfWarfare: I just like being explicit. – Xeo Mar 10 '13 at 20:55
82
#include <algorithm>
static const size_t v_size = 2000;
int v[v_size];
// Fill the array by values
std::sort(v, v + v_size); 

In C++11:

#include <algorithm>
#include <array>
std::array<int, 2000> v;
// Fill the array by values
std::sort(v.begin(), v.end()); 
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Naszta
  • 7,560
  • 2
  • 33
  • 49
  • 5
    +1: Correct but very brittle. If the sort is not near the declaration this can easily be broken during maintenance. – Martin York May 05 '11 at 15:16
  • 1
    @Martin: true. That's why I prefer to use `std::vector`. My code would be: `std::vector v(2000); std::sort( v.begin(), v.end() );` – Naszta May 05 '11 at 15:19
  • 2
    Of course, using literal array sizes is always dangerous, as in the example. But there is nothing wrong with putting the array size into a 'const int'. – Kai Petzke Sep 19 '13 at 18:39
34

If you don't know the size, you can use:

std::sort(v, v + sizeof v / sizeof v[0]);

Even if you do know the size, it's a good idea to code it this way as it will reduce the possibility of a bug if the array size is changed later.

j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
  • 3
    If it is statically allocated, he should know the size, because the compiler knows. But this is better coding practice. – Benoit May 05 '11 at 12:11
  • 8
    Since you are writting future proof code, instead of using the `sizeof x/sizeof *x` trick you should use a safer template: `template int array_size( T (&)[N] ) { return N; }`, as that will fail if instead of an array you pass a pointer. It can be converted into a compile time constant if needed, but it becomes a little too hard to read in a comment. – David Rodríguez - dribeas May 05 '11 at 12:16
  • 1
    @David: Good idea, but an even better (and dare I say The Right) way is to define `begin()` and `end()` function templates that are specialised for all common container types, including arrays, and use them instead. Xeo's answer made me think these had already been added to C++, now it seems they haven't... I'll see what else people have to say and then update. – j_random_hacker May 05 '11 at 12:21
  • 1
    :) I have a small utility header that has a few bits like this, including `begin`, `end`, `size`, `STATIC_SIZE` (macro that returns a compile time constant with the size), but to be honest, I hardly ever use that outside of small code samples. – David Rodríguez - dribeas May 05 '11 at 14:39
  • 1
    The size of an array can be received by `std::extent::value` in C++11 – xis Jul 29 '13 at 20:36
20

You can sort it std::sort(v, v + 2000)

P0W
  • 46,614
  • 9
  • 72
  • 119
Mayank
  • 5,454
  • 9
  • 37
  • 60
  • 6
    +1: Correct but very brittle. If the sort is not near the declaration this can easily be broken during maintenance. – Martin York May 05 '11 at 15:16
3
#include<iostream>
using namespace std;
void main()
{
    int a[5];
    int temp = 0;
    cout << "Enter Values: " << endl;

    for(int i = 0; i < 5; i++)
        cin >> a[i];
    for(int i = 0; i < 5; i++)
        for(int j = 0; j < 5; j++)
            if(a[i] > a[j])
            {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
    cout << "Asending Series" << endl;
    for(int i = 0; i < 5; i++)
    {
        cout << endl;
        cout << a[i] << endl;
    }

    for(int i = 0; i < 5; i++)
        for(int j = 0; j < 5; j++)
            if(a[i] < a[j])
            {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
    cout << "Desending Series" << endl;
    for(int i = 0;i < 5; i++)
    {
        cout << endl;
        cout << a[i] << endl;
    }
}
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
wahid Butt
  • 39
  • 1
2

you can use sort() in C++ STL. sort() function Syntax :

 sort(array_name, array_name+size)      

 So you use  sort(v, v+2000);
rashedcs
  • 3,588
  • 2
  • 39
  • 40
2

It is as simple as that ... C++ is providing you a function in STL (Standard Template Library) called sort which runs 20% to 50% faster than the hand-coded quick-sort.

Here is the sample code for it's usage:

std::sort(arr, arr + size);
L. F.
  • 19,445
  • 8
  • 48
  • 82
1
//sort by number
bool sortByStartNumber(Player &p1, Player &p2) {
    return p1.getStartNumber() < p2.getStartNumber();
}
//sort by string
bool sortByName(Player &p1, Player &p2) {
    string s1 = p1.getFullName();
    string s2 = p2.getFullName();
    return s1.compare(s2) == -1;
}
  • Welcome to Stack Overflow. Answers that provide only code, without any explanation, are generally frowned upon, especially when a) there are many answers already provided, and b) an answer has already been accepted. Please elaborate on why your solution is different and/or better from the 12 that have already been posted. – chb Jan 17 '19 at 00:37
1

With the Ranges library that is coming in C++20, you can use

ranges::sort(arr);

directly, where arr is a builtin array.

L. F.
  • 19,445
  • 8
  • 48
  • 82
1

sort() can be applied on both array and vector in C++ to sort or re-arrange elements .

1. C++ sort() in case of a vector:

// importing vector, algorithm & iostream

using namespace std;

int main() {

vector v = {5,4,3,2,8}; // depending on your vector size

sort(v.begin(), v.end());

cout<<v[1]; //testing the sorted element positions by printing

return 0;

}

2. C++ sort() in case of an array:

// including algorithm & iostream

using namespace std;

int main() {

int array[] = {10, 35, 85}; // array size 2000 in your case int n = sizeof(array)/sizeof(array[0]);

sort(array, array+3);

cout<<array[0];

return 0;

}

Note: Both the above snippets were tested with modern C++ versions (11,17 & 20) before posting here .

Farial Mahmod
  • 61
  • 1
  • 4
0

sorting method without std::sort:

// sorting myArray ascending
int iTemp = 0;
for (int i = 0; i < ARRAYSIZE; i++)
{
    for (int j = i + 1; j <= ARRAYSIZE; j++)
    {
        // for descending sort change '<' with '>'
        if (myArray[j] < myArray[i])
        {
            iTemp = myArray[i];
            myArray[i] = myArray[j];
            myArray[j] = iTemp;
        }
    }
}

Run complete example:

#include <iostream> // std::cout, std::endl /* http://en.cppreference.com/w/cpp/header/iostream */
#include <cstdlib>  // srand(), rand()      /* http://en.cppreference.com/w/cpp/header/cstdlib */
#include <ctime>    // time()               /* http://en.cppreference.com/w/cpp/header/ctime */


int main()
{
    const int ARRAYSIZE = 10;
    int myArray[ARRAYSIZE];

    // populate myArray with random numbers from 1 to 1000
    srand(time(0));
    for (int i = 0; i < ARRAYSIZE; i++)
    {
        myArray[i] = rand()% 1000 + 1;
    }

    // print unsorted myArray
    std::cout << "unsorted myArray: " << std::endl;
    for (int i = 0; i < ARRAYSIZE; i++)
    {
        std::cout << "[" << i << "] -> " << myArray[i] << std::endl;
    }
    std::cout << std::endl;

    // sorting myArray ascending
    int iTemp = 0;
    for (int i = 0; i < ARRAYSIZE; i++)
    {
        for (int j = i + 1; j <= ARRAYSIZE; j++)
        {
            // for descending sort change '<' with '>'
            if (myArray[j] < myArray[i])
            {
                iTemp = myArray[i];
                myArray[i] = myArray[j];
                myArray[j] = iTemp;
            }
        }
    }

    // print sorted myArray
    std::cout << "sorted myArray: " << std::endl;
    for (int i = 0; i < ARRAYSIZE; i++)
    {
        std::cout << "[" << i << "] -> " << myArray[i] << std::endl;
    }
    std::cout << std::endl;

    return 0;
}
  • 1
    Really? You want to use a slow bubble sort instead of the standard library? Not only that, you have an off-by-one error causing UB. – Mark Ransom Jan 05 '17 at 21:31
0

Use the C++ std::sort function:

#include <algorithm>
using namespace std;

int main()
{
  vector<int> v(2000);
  sort(v.begin(), v.end());
}
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
-1

C++ sorting using sort function

#include <bits/stdc++.h>
 using namespace std;

vector <int> v[100];

int main()
{
  sort(v.begin(), v.end());
}
Mahedi Hasan Durjoy
  • 1,031
  • 13
  • 17
-2

you can use,

 std::sort(v.begin(),v.end());
Rohit Hajare
  • 125
  • 1
  • 7