Como usar std :: sort para classificar uma matriz em C ++


90

Como usar a biblioteca de modelos padrão std::sort()para classificar uma matriz declarada como int v[2000];

C ++ fornece alguma função que pode obter o índice inicial e final de uma matriz?

Respostas:


109

Em C ++ 0x / 11, obtemos std::begine std::endque estão sobrecarregados de matrizes:

#include <algorithm>

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

Se você não tem acesso a C ++ 0x, não é difícil escrevê-los você mesmo:

// 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
São std::begin()e std::end()C ++ 1x adições? Eles são muito legais - deveriam ter sido assim desde o início, teria tornado muitos algoritmos mais genéricos!
j_random_hacker

10
std::begin()e std::end()não fazem parte do padrão C ++ atual, mas você pode usar boost::begin()e boost::end().
Kirill V. Lyadvinsky

1
Editado de acordo com os comentários.
Xeo

2
Apenas um lembrete: muito antes de eles serem propostos para C ++ 11, a maioria de nós tinha essa função begine endem nossos kits de ferramentas pessoais. Antes do C ++ 11, entretanto, eles tinham uma grande desvantagem: eles não resultavam em uma expressão constante integral. Então, dependendo das necessidades específicas, nós usávamos, ou uma macro que fazia a divisão dos dois sizeof.
James Kanze

1
@Xeo Não tenho certeza se entendi o que você está dizendo. decltypecertamente simplifica certos usos, mas não vejo o que isso tem a ver com o free begine as endfunções. (E você realmente deve ter dois cada um deles, um para arrays de estilo C e outro para contêineres, com discriminação automática, para que possa usá-los em modelos, sem saber se o tipo é um contêiner ou um array de estilo C.)
James Kanze

70
#include <algorithm>
static const size_t v_size = 2000;
int v[v_size];
// Fill the array by values
std::sort(v,v+v_size); 

Em C ++ 11 :

#include <algorithm>
#include <array>
std::array<int, 2000> v;
// Fill the array by values
std::sort(v.begin(),v.end()); 

5
+1: correto, mas muito frágil. Se a classificação não estiver perto da declaração, isso pode ser facilmente quebrado durante a manutenção.
Martin York

1
@Martin: verdadeiro. É por isso que prefiro usar std::vector. Meu código seria:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Naszta

2
Obviamente, usar tamanhos de array literais é sempre perigoso, como no exemplo. Mas não há nada de errado em colocar o tamanho do array em um 'const int'.
Kai Petzke

31

Se você não souber o tamanho, pode usar:

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

Mesmo se você souber o tamanho, é uma boa ideia codificá-lo dessa forma, pois isso reduzirá a possibilidade de um bug se o tamanho do array for alterado posteriormente.


3
Se for alocado estaticamente, ele deve saber o tamanho, pois o compilador sabe. Mas esta é uma prática de codificação melhor.
Benoit

7
Já que você está escrevendo um código para o futuro, em vez de usar o sizeof x/sizeof *xtruque, você deve usar um modelo mais seguro:, template <typename T, int N> int array_size( T (&)[N] ) { return N; }pois isso falhará se em vez de um array você passar um ponteiro. Ele pode ser convertido em uma constante de tempo de compilação, se necessário, mas torna-se um pouco difícil de ler em um comentário.
David Rodríguez - dribeas

1
@David: Boa ideia, mas uma maneira ainda melhor (e ouso dizer a Certa) é definir begin()e end()funcionar modelos especializados para todos os tipos de contêineres comuns, incluindo arrays, e usá-los em seu lugar. A resposta de Xeo me fez pensar que eles já tinham sido adicionados ao C ++, agora parece que não ... Vou ver o que mais as pessoas têm a dizer e depois atualizar.
j_random_hacker

1
:) Eu tenho um pequeno cabeçalho utilitário que tem alguns pedaços como este, incluindo begin, end, size, STATIC_SIZE(macro que retorna uma constante de tempo de compilação com o tamanho), mas para ser honesto, eu quase nunca usar isso fora de amostras de código pequeno.
David Rodríguez - dribeas

1
O tamanho de uma matriz pode ser recebido por std::extent<decltype(v)>::valueem C ++ 11
xis

18

Você pode ordenar std::sort(v, v + 2000)


4
+1: correto, mas muito frágil. Se a classificação não estiver perto da declaração, isso pode ser facilmente quebrado durante a manutenção.
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

você pode usar sort () em C ++ STL. Sintaxe da função sort ():

 sort(array_name, array_name+size)      

 So you use  sort(v, v+2000);

1

Classificação C ++ usando a função de classificação

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

vector <int> v[100];

int main()
{
  sort(v.begin(), v.end());
}

Este funciona em uma versão mais antiga. Eu tentei com isto:std::sort(arr, arr + arr_size)
Code Cooker

Isso não funciona de jeito nenhum. Não quer dizer que não seja C ++.
LF

1

Use a std::sortfunção 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;
}

Bem-vindo ao Stack Overflow. Respostas que fornecem apenas código, sem qualquer explicação, geralmente são desaprovadas, especialmente quando a) há muitas respostas já fornecidas, eb) uma resposta já foi aceita. Explique por que sua solução é diferente e / ou melhor das 12 que já foram postadas.
chb

1

É tão simples quanto isso ... C ++ está fornecendo a você uma função chamada STL (Standard Template Library) sortque é executada de 20% a 50% mais rápido do que a classificação rápida codificada manualmente.

Aqui está o código de amostra para seu uso:

std::sort(arr, arr + size);

1

Com a biblioteca Ranges que vem em C ++ 20, você pode usar

ranges::sort(arr);

diretamente, onde arrestá um array embutido.


0

método de classificação sem 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;
        }
    }
}

Execute um exemplo 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
Realmente? Você deseja usar uma classificação de bolha lenta em vez da biblioteca padrão? Não só isso, você tem um erro off-by-one causando UB.
Mark Ransom

-1

você pode usar,

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

Olá, esta pergunta já parece ter uma resposta amplamente aceita. Você pode explicar como isso é diferente?
Stefan

Os arrays não têm métodos begine end. Você deve estar pensando em a vector.
Mark Ransom
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.