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?

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

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

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.


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)


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


}

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

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

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

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

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

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.


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

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.