Cómo usar std :: sort para ordenar una matriz en C ++

91

Cómo utilizar la biblioteca de plantillas estándar std::sort()para ordenar una matriz declarada como int v[2000];

¿C ++ proporciona alguna función que pueda obtener el índice inicial y final de una matriz?

Varaquilex
fuente

Respuestas:

111

En C ++ 0x / 11 obtenemos std::beginy std::endcuáles están sobrecargados para matrices:

#include <algorithm>

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

Si no tiene acceso a C ++ 0x, no es difícil escribirlos usted mismo:

// 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
fuente
12
¿Son std::begin()y std::end()C ++ 1x adiciones? Son muy agradables, debería haber sido así desde el principio, ¡habría hecho que muchos algoritmos fueran más genéricos!
j_random_hacker
10
std::begin()y std::end()no forman parte del estándar C ++ actual, pero puede usar boost::begin()y boost::end().
Kirill V. Lyadvinsky
1
Editado de acuerdo con los comentarios.
Xeo
2
Sólo un recordatorio: mucho antes de que fueran a propuesta para C ++ 11, la mayoría de nosotros tenía tal beginy endfunción en nuestros juegos de herramientas personales. Antes de C ++ 11, sin embargo, tenían una gran desventaja: no daban como resultado una expresión constante integral. Entonces, dependiendo de las necesidades específicas, las usaríamos, o una macro que hiciera la división de las dos sizeof.
James Kanze
1
@Xeo No estoy seguro de entender lo que estás diciendo. decltypeciertamente simplifica ciertos usos, pero no veo qué tiene que ver con las funciones gratuitas beginy end. (Y realmente debería tener dos de cada uno, uno para matrices de estilo C y otro para contenedores, con discriminación automática, para que pueda usarlos en plantillas, sin saber si el tipo es un contenedor o una matriz de estilo C.)
James Kanze
71
#include <algorithm>
static const size_t v_size = 2000;
int v[v_size];
// Fill the array by values
std::sort(v,v+v_size); 

En C ++ 11 :

#include <algorithm>
#include <array>
std::array<int, 2000> v;
// Fill the array by values
std::sort(v.begin(),v.end()); 
Naszta
fuente
5
+1: Correcto pero muy frágil. Si el tipo no está cerca de la declaración, esto se puede romper fácilmente durante el mantenimiento.
Martin York
1
@Martin: cierto. Por eso prefiero usar std::vector. Mi código sería:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Naszta
2
Por supuesto, usar tamaños de matriz literales siempre es peligroso, como en el ejemplo. Pero no hay nada de malo en poner el tamaño de la matriz en un 'const int'.
Kai Petzke
31

Si no conoce el tamaño, puede usar:

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

Incluso si conoce el tamaño, es una buena idea codificarlo de esta manera, ya que reducirá la posibilidad de un error si el tamaño de la matriz se cambia más tarde.

j_random_hacker
fuente
3
Si está asignado estáticamente, debe conocer el tamaño, porque el compilador lo sabe. Pero esta es una mejor práctica de codificación.
Benoit
7
Ya que está escribiendo código de prueba futura, en lugar de usar el sizeof x/sizeof *xtruco, debe usar una plantilla más segura:, template <typename T, int N> int array_size( T (&)[N] ) { return N; }ya que fallará si en lugar de una matriz pasa un puntero. Se puede convertir en una constante de tiempo de compilación si es necesario, pero se vuelve un poco difícil de leer en un comentario.
David Rodríguez - dribeas
1
@ David: Buena idea, pero aún mejor (y me atrevo a decir la derecha) forma es definir begin()y end()función de las plantillas que están especializados para todo tipo de contenedores comunes, incluyendo matrices, y utilizar en su lugar. La respuesta de Xeo me hizo pensar que estos ya se habían agregado a C ++, ahora parece que no ... Veré qué más tiene que decir la gente y luego actualizar.
j_random_hacker
1
:) Tengo una pequeña cabecera utilidad que tiene unos pocos bits de este tipo, incluyendo begin, end, size, STATIC_SIZE(macro que devuelve una constante de tiempo de compilación con el tamaño), pero para ser honesto, yo casi nunca utilizan que, fuera de pequeñas muestras de código.
David Rodríguez - dribeas
1
El tamaño de una matriz se puede recibir std::extent<decltype(v)>::valueen C ++ 11
xis
18

Puedes ordenarlo std::sort(v, v + 2000)

Mayank
fuente
4
+1: Correcto pero muy frágil. Si el tipo no está cerca de la declaración, esto se puede romper fácilmente durante el mantenimiento.
Martin York
3
//It is working
#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<<"Desnding Series"<<endl;
    for(int i=0;i<5;i++)
    {
        cout<<endl;
        cout<<a[i]<<endl;
    }


}
trasero de wahid
fuente
2

puede usar sort () en C ++ STL. Sintaxis de la función sort ():

 sort(array_name, array_name+size)      

 So you use  sort(v, v+2000);
rashedcs
fuente
2

Es tan simple como eso ... C ++ le proporciona una función en STL (Biblioteca de plantillas estándar) llamada sortque se ejecuta entre un 20% y un 50% más rápido que la clasificación rápida codificada a mano.

Aquí está el código de muestra para su uso:

std::sort(arr, arr + size);
risheek reddy
fuente
1

Clasificación de C ++ usando la función de clasificación

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

vector <int> v[100];

int main()
{
  sort(v.begin(), v.end());
}
Mahedi Hasan Durjoy
fuente
Este funciona en una versión anterior. Intenté con esto:std::sort(arr, arr + arr_size)
Code Cooker
Esto no funciona en absoluto. Por no decir que no es C ++.
LF
1

Utilice la std::sortfunción C ++ :

#include <algorithm>
using namespace std;

int main()
{
  vector<int> v(2000);
  sort(v.begin(), v.end());
}
Toby Speight
fuente
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;
}
usuario5465465465
fuente
Bienvenido a Stack Overflow. Las respuestas que solo proporcionan código, sin ninguna explicación, generalmente están mal vistas, especialmente cuando a) ya se han proporcionado muchas respuestas yb) ya se ha aceptado una respuesta. Explique por qué su solución es diferente y / o mejor de las 12 que ya se han publicado.
chb
1

Con la biblioteca Ranges que viene en C ++ 20, puede usar

ranges::sort(arr);

directamente, donde arrhay una matriz incorporada.

LF
fuente
0

método de clasificación sin 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;
        }
    }
}

Ejecute el ejemplo completo:

#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;
}
usuario6021501
fuente
1
De Verdad? ¿Desea utilizar una clasificación de burbujas lenta en lugar de la biblioteca estándar? No solo eso, tiene un error de uno en uno que causa UB.
Mark Ransom
-1

puedes usar,

 std::sort(v.begin(),v.end());
Rohit Hajare
fuente
Hola, esta pregunta ya parece tener una respuesta ampliamente aceptada. ¿Puedes explicar en qué se diferencia esto?
Stefan
Las matrices no tienen métodos beginy end. Debes estar pensando en a vector.
Mark Ransom