Verwendung von std :: sort zum Sortieren eines Arrays in C ++


89

Verwendung der Standardvorlagenbibliothek std::sort() zum Sortieren eines als deklarierten Arrays int v[2000];

Bietet C ++ eine Funktion, mit der der Anfangs- und Endindex eines Arrays abgerufen werden kann?

Antworten:


108

In C ++ 0x / 11 erhalten wir std::beginund std::enddie für Arrays überladen sind:

#include <algorithm>

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

Wenn Sie keinen Zugriff auf C ++ 0x haben, ist es nicht schwer, sie selbst zu schreiben:

// 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
Sind std::begin()und std::end()C ++ 1x Ergänzungen? Sie sind sehr nett - hätte von Anfang an so sein sollen, es hätte viele Algorithmen allgemeiner gemacht!
j_random_hacker

10
std::begin()und std::end()sind nicht Teil des aktuellen C ++ - Standards, aber Sie können boost::begin()und verwenden boost::end().
Kirill V. Lyadvinsky

1
Entsprechend den Kommentaren bearbeitet.
Xeo

2
Nur zur Erinnerung: lange , bevor sie vorgeschlagen für C ++ waren 11, hatten die meisten von uns eine solche beginund endFunktion in unserem persönlichen Tool - Kits. Vor C ++ 11 hatten sie jedoch einen seriellen Nachteil: Sie führten nicht zu einem integralen konstanten Ausdruck. Abhängig von den spezifischen Anforderungen würden wir sie verwenden oder ein Makro, das die Aufteilung der beiden vornimmt sizeof.
James Kanze

1
@Xeo Ich bin nicht sicher, ob ich verstehe, was du sagst. decltypesicherlich vereinfacht bestimmte Verwendungen, aber ich sehe nicht, was es mit dem freien beginund endFunktionen zu tun hat . (Und Sie sollten wirklich jeweils zwei davon haben, eines für Arrays im C-Stil und eines für Container mit automatischer Unterscheidung, damit Sie sie in Vorlagen verwenden können, ohne zu wissen, ob der Typ ein Container oder ein Array im C-Stil ist.)
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); 

In C ++ 11 :

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

5
+1: Richtig, aber sehr spröde. Wenn sich die Sortierung nicht in der Nähe der Deklaration befindet, kann dies während der Wartung leicht beschädigt werden.
Martin York

1
@ Martin: wahr. Deshalb benutze ich lieber std::vector. Mein Code wäre:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Naszta

2
Natürlich ist die Verwendung von Literal-Array-Größen wie im Beispiel immer gefährlich. Es ist jedoch nichts Falsches daran, die Arraygröße in eine 'const int' zu setzen.
Kai Petzke

31

Wenn Sie die Größe nicht kennen, können Sie Folgendes verwenden:

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

Selbst wenn Sie die Größe kennen, ist es eine gute Idee, sie auf diese Weise zu codieren, da dies die Möglichkeit eines Fehlers verringert, wenn die Arraygröße später geändert wird.


3
Wenn es statisch zugeordnet ist, sollte er die Größe kennen, da der Compiler es weiß. Dies ist jedoch eine bessere Codierungspraxis.
Benoit

7
Da Sie zukunftssicheren Code schreiben, sollten Sie anstelle des sizeof x/sizeof *xTricks eine sicherere Vorlage verwenden :, template <typename T, int N> int array_size( T (&)[N] ) { return N; }da dies fehlschlägt, wenn Sie anstelle eines Arrays einen Zeiger übergeben. Es kann bei Bedarf in eine Kompilierungszeitkonstante umgewandelt werden, ist jedoch etwas zu schwer in einem Kommentar zu lesen.
David Rodríguez - Dribeas

1
@ David: Gute Idee, aber eine noch bessere (und ich wage es zu sagen die richtige) Möglichkeit besteht darin, Vorlagen zu definieren begin()und zu end()funktionieren, die auf alle gängigen Containertypen, einschließlich Arrays, spezialisiert sind, und sie stattdessen zu verwenden. Die Antwort von Xeo ließ mich denken, dass diese bereits zu C ++ hinzugefügt wurden, jetzt scheinen sie es nicht getan zu haben ... Ich werde sehen, was die Leute sonst noch zu sagen haben und dann aktualisieren.
j_random_hacker

1
:) Ich habe einen kleinen Programm - Header, der ein paar Bits wie diese hat, einschließlich begin, end, size, STATIC_SIZE(Makro , dass die Renditen der Kompilierung ein Zeitkonstante mit der Größe), aber um ehrlich zu sein, den ich je kaum , dass außerhalb von kleinen Codebeispielen verwenden.
David Rodríguez - Dribeas

1
Die Größe eines Arrays kann von std::extent<decltype(v)>::valuein C ++ 11
empfangen werden

18

Sie können es sortieren std::sort(v, v + 2000)


4
+1: Richtig, aber sehr spröde. Wenn sich die Sortierung nicht in der Nähe der Deklaration befindet, kann dies während der Wartung leicht beschädigt werden.
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

Sie können sort () in C ++ STL verwenden. sort () Funktion Syntax:

 sort(array_name, array_name+size)      

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

1

C ++ - Sortierung mit Sortierfunktion

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

vector <int> v[100];

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

Dieser funktioniert auf älteren Versionen. Ich habe es damit versucht:std::sort(arr, arr + arr_size)
Code Cooker

Das funktioniert überhaupt nicht. Um nicht zu sagen, es ist nicht C ++.
LF

1

Verwenden Sie die C ++ - std::sortFunktion:

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

Willkommen bei Stack Overflow. Antworten, die nur Code ohne Erklärung enthalten, werden im Allgemeinen verpönt, insbesondere wenn a) bereits viele Antworten bereitgestellt wurden und b) eine Antwort bereits akzeptiert wurde. Bitte erläutern Sie, warum sich Ihre Lösung von den bereits veröffentlichten 12 unterscheidet und / oder besser ist.
chb

1

So einfach ist das ... C ++ bietet Ihnen eine Funktion in STL (Standard Template Library), sortdie 20% bis 50% schneller ausgeführt wird als die handcodierte Schnellsortierung.

Hier ist der Beispielcode für seine Verwendung:

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

1

Mit der Ranges-Bibliothek, die in C ++ 20 enthalten ist, können Sie verwenden

ranges::sort(arr);

direkt, wo arrist ein eingebautes Array.


0

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

Führen Sie ein vollständiges Beispiel aus:

#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
"Ja wirklich?" Sie möchten eine langsame Blasensortierung anstelle der Standardbibliothek verwenden? Darüber hinaus haben Sie einen Fehler, der UB verursacht.
Mark Ransom

-1

Sie können verwenden,

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

Hallo, diese Frage scheint bereits eine allgemein akzeptierte Antwort zu haben. Können Sie erklären, wie das anders ist?
Stefan

Arrays haben keine beginund endMethoden. Sie müssen an a denken vector.
Mark Ransom
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.