Comment utiliser std :: sort pour trier un tableau en C ++


90

Comment utiliser la bibliothèque de modèles standard std::sort()pour trier un tableau déclaré comme int v[2000] ;

Le C ++ fournit-il une fonction qui peut obtenir l'index de début et de fin d'un tableau?

Réponses:


109

En C ++ 0x / 11, nous obtenons std::beginet std::endqui sont surchargés pour les tableaux:

#include <algorithm>

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

Si vous n'avez pas accès à C ++ 0x, il n'est pas difficile de les écrire vous-même:

// 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
Sont des ajouts std::begin()et std::end()C ++ 1x? Ils sont très gentils - cela aurait dû être ainsi depuis le début, cela aurait rendu beaucoup d'algorithmes plus génériques!
j_random_hacker

10
std::begin()et std::end()ne font pas partie de la norme C ++ actuelle, mais vous pouvez utiliser boost::begin()et boost::end().
Kirill V. Lyadvinsky

1
Modifié en fonction des commentaires.
Xeo

2
Juste un rappel: bien avant qu'ils ne soient proposés pour C ++ 11, la plupart d'entre nous en avaient un beginet endfonctionnaient dans nos kits d'outils personnels. Avant C ++ 11, cependant, ils avaient un inconvénient serios: ils ne résultaient pas en une expression constante intégrale. Donc, en fonction des besoins spécifiques, nous les utiliserions, ou une macro qui faisait la division des deux sizeof.
James Kanze

1
@Xeo Je ne suis pas sûr de comprendre ce que vous dites. decltypesimplifie certainement certaines utilisations, mais je ne vois pas ce que cela a à voir avec les fonctions gratuites beginet end. (Et vous devriez vraiment en avoir deux pour chacun d'eux, un pour les tableaux de style C et un autre pour les conteneurs, avec discrimination automatique, afin de pouvoir les utiliser dans des modèles, sans savoir si le type est un conteneur ou un tableau de style 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); 

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: Correct mais très fragile. Si le tri n'est pas proche de la déclaration, cela peut facilement être cassé pendant la maintenance.
Martin York

1
@Martin: vrai. C'est pourquoi je préfère utiliser std::vector. Mon code serait:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Naszta

2
Bien sûr, l'utilisation de tailles de tableau littérales est toujours dangereuse, comme dans l'exemple. Mais il n'y a rien de mal à mettre la taille du tableau dans un 'const int'.
Kai Petzke

31

Si vous ne connaissez pas la taille, vous pouvez utiliser:

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

Même si vous connaissez la taille, c'est une bonne idée de le coder de cette façon car cela réduira la possibilité d'un bogue si la taille du tableau est modifiée plus tard.


3
S'il est alloué statiquement, il doit connaître la taille, car le compilateur le sait. Mais c'est une meilleure pratique de codage.
Benoit

7
Puisque vous écrivez du code de preuve future, au lieu d'utiliser l' sizeof x/sizeof *xastuce, vous devriez utiliser un modèle plus sûr:, template <typename T, int N> int array_size( T (&)[N] ) { return N; }car cela échouera si au lieu d'un tableau, vous passez un pointeur. Il peut être converti en une constante de temps de compilation si nécessaire, mais il devient un peu trop difficile à lire dans un commentaire.
David Rodríguez - dribeas

1
@David: Bonne idée, mais une manière encore meilleure (et j'ose dire la bonne) est de définir begin()et de faire end()fonctionner des modèles spécialisés pour tous les types de conteneurs courants, y compris les tableaux, et de les utiliser à la place. La réponse de Xeo m'a fait penser que ceux-ci avaient déjà été ajoutés au C ++, maintenant il semble qu'ils ne l'ont pas fait ... Je vais voir ce que les autres ont à dire et puis mettre à jour.
j_random_hacker

1
:) J'ai une petite tête utilitaire qui a quelques bits comme celui - ci, y compris begin, end, size, STATIC_SIZE(macro qui renvoie un constante de temps de compilation avec la taille), mais pour être honnête, j'utilise presque jamais que , en dehors des petits échantillons de code.
David Rodríguez - dribeas

1
La taille d'un tableau peut être reçue std::extent<decltype(v)>::valueen C ++ 11
xis

18

Vous pouvez le trier std::sort(v, v + 2000)


4
+1: Correct mais très fragile. Si le tri n'est pas proche de la déclaration, cela peut facilement être cassé pendant la maintenance.
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

vous pouvez utiliser sort () dans C ++ STL. Fonction sort () Syntaxe:

 sort(array_name, array_name+size)      

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

1

Tri C ++ à l'aide de la fonction de tri

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

vector <int> v[100];

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

Celui-ci fonctionne sur une version plus ancienne. J'ai essayé avec ceci:std::sort(arr, arr + arr_size)
Code Cooker

Cela ne fonctionne pas du tout. Pour ne pas dire que ce n'est pas du C ++.
LF

1

Utilisez la std::sortfonction 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;
}

Bienvenue dans Stack Overflow. Les réponses qui ne fournissent que du code, sans aucune explication, sont généralement mal vues, surtout quand a) de nombreuses réponses sont déjà fournies, et b) une réponse a déjà été acceptée. Veuillez expliquer pourquoi votre solution est différente et / ou meilleure que les 12 qui ont déjà été publiées.
chb

1

C'est aussi simple que cela ... C ++ vous fournit une fonction en STL (Standard Template Library) appelée sort qui s'exécute 20% à 50% plus vite que le tri rapide codé à la main.

Voici l'exemple de code pour son utilisation:

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

1

Avec la bibliothèque Ranges fournie en C ++ 20, vous pouvez utiliser

ranges::sort(arr);

directement, où arrest un tableau intégré.


0

méthode de tri sans 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;
        }
    }
}

Exécutez l' exemple complet:

#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
Vraiment? Vous souhaitez utiliser un tri à bulles lent au lieu de la bibliothèque standard? Non seulement cela, vous avez une erreur hors-un-par-un causant UB.
Mark Ransom

-1

vous pouvez utiliser,

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

Salut, cette question semble déjà avoir une réponse largement acceptée. Pouvez-vous expliquer en quoi cela est différent?
Stefan

Les tableaux n'ont pas de méthodes beginet end. Vous devez penser à un vector.
Mark Ransom
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.