Jak używać std :: sort do sortowania tablicy w C ++


91

Jak używać biblioteki szablonów standardowych std::sort()do sortowania tablicy zadeklarowanej jako int v[2000];

Czy C ++ udostępnia jakąś funkcję, która może pobrać indeks początkowy i końcowy tablicy?

Odpowiedzi:


111

W C ++ 0x / 11 otrzymujemy std::begini std::endktóre są przeciążone dla tablic:

#include <algorithm>

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

Jeśli nie masz dostępu do C ++ 0x, nie jest trudno napisać je samemu:

// 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
Czy są std::begin()i std::end()C ++ 1x dodatki? Są bardzo ładne - powinno tak być od samego początku, dzięki temu wiele algorytmów byłoby bardziej ogólnych!
j_random_hacker

10
std::begin()i std::end()nie są częścią obecnego standardu C ++, ale możesz używać boost::begin()i boost::end().
Kirill V. Lyadvinsky

1
Zredagowano zgodnie z komentarzami.
Xeo

2
Tak dla przypomnienia: na długo zanim miały one proponowane dla c ++ 11, większość z nas nie miał takiej begini endfunkcję w naszych zestawów narzędziowych osobowych. Jednak przed C ++ 11 miały poważną wadę: nie dawały integralnego wyrażenia stałego. Więc w zależności od konkretnych potrzeb używalibyśmy ich lub makra, które dzieliło te dwa elementy sizeof.
James Kanze

1
@Xeo Nie jestem pewien, czy rozumiem, co mówisz. decltypez pewnością upraszcza niektóre zastosowania, ale nie widzę, co to ma wspólnego z darmowymi begini endfunkcjami. (I naprawdę powinieneś mieć po dwie z nich, jedną dla tablic w stylu C, a drugą dla kontenerów, z automatycznym rozróżnianiem, więc możesz ich używać w szablonach, nie wiedząc, czy typ jest kontenerem, czy tablicą w stylu 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); 

W C ++ 11 :

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

5
+1: Poprawne, ale bardzo kruche. Jeśli rodzaj nie znajduje się w pobliżu deklaracji, można to łatwo zepsuć podczas konserwacji.
Martin York

1
@Martin: prawda. Dlatego wolę używać std::vector. Mój kod to:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Naszta

2
Oczywiście używanie literalnych rozmiarów tablic jest zawsze niebezpieczne, jak w przykładzie. Ale nie ma nic złego w umieszczaniu rozmiaru tablicy w „const int”.
Kai Petzke

31

Jeśli nie znasz rozmiaru, możesz użyć:

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

Nawet jeśli znasz rozmiar, dobrym pomysłem jest zakodowanie go w ten sposób, ponieważ zmniejszy to możliwość wystąpienia błędu, jeśli rozmiar tablicy zostanie zmieniony później.


3
Jeśli jest przydzielony statycznie, powinien znać rozmiar, ponieważ kompilator wie. Ale to jest lepsza praktyka kodowania.
Benoit

7
Ponieważ piszesz kod przyszłości, zamiast używać sizeof x/sizeof *xsztuczki, powinieneś użyć bezpieczniejszego szablonu:, template <typename T, int N> int array_size( T (&)[N] ) { return N; }ponieważ to się nie powiedzie, jeśli zamiast tablicy przekażesz wskaźnik. W razie potrzeby można go przekształcić w stałą czasową kompilacji, ale w komentarzu staje się to trochę zbyt trudne.
David Rodríguez - dribeas

1
@David: Dobry pomysł, ale jeszcze lepszym (i ośmielę się powiedzieć właściwy) sposobem jest zdefiniowanie begin()i wykorzystanie end()szablonów, które są wyspecjalizowane dla wszystkich popularnych typów kontenerów, w tym tablic, i używanie ich zamiast tego. Odpowiedź Xeo sprawiła, że ​​pomyślałem, że zostały one już dodane do C ++, teraz wygląda na to, że nie ... Zobaczę, co jeszcze ludzie mają do powiedzenia, a następnie zaktualizuję.
j_random_hacker

1
:) Mam mały nagłówek narzędziowy, który ma kilka bitów w ten sposób, w tym begin, end, size, STATIC_SIZE(makro, które powraca stałym czasie kompilacji z rozmiarem), ale szczerze mówiąc, ja prawie nigdy nie używać, że poza małymi próbkami kodu.
David Rodríguez - dribeas

1
Rozmiar tablicy można std::extent<decltype(v)>::value
odczytać

18

Możesz to posortować std::sort(v, v + 2000)


4
+1: Poprawne, ale bardzo kruche. Jeśli rodzaj nie znajduje się w pobliżu deklaracji, można to łatwo zepsuć podczas konserwacji.
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

możesz użyć sort () w C ++ STL. sort () funkcja Składnia:

 sort(array_name, array_name+size)      

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

2

To takie proste ... C ++ udostępnia funkcję w STL (Standard Template Library) o nazwie, sortktóra działa od 20% do 50% szybciej niż ręcznie kodowane szybkie sortowanie.

Oto przykładowy kod do jego użycia:

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

1

Sortowanie w C ++ przy użyciu funkcji sortowania

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

vector <int> v[100];

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

Ten działa na starszej wersji. Próbowałem z tym:std::sort(arr, arr + arr_size)
Code Cooker

To w ogóle nie działa. Nie znaczy to, że nie jest to C ++.
LF,

1

Użyj funkcji C ++ std::sort:

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

Witamy w Stack Overflow. Odpowiedzi, które zawierają tylko kod, bez żadnego wyjaśnienia, są generalnie mile widziane, zwłaszcza gdy a) istnieje wiele już udzielonych odpowiedzi oraz b) odpowiedź została już zaakceptowana. Opisz, dlaczego Twoje rozwiązanie jest inne i / lub lepsze od 12, które zostały już opublikowane.
chb

1

Dzięki bibliotece Ranges, która pojawi się w C ++ 20, możesz używać

ranges::sort(arr);

bezpośrednio, gdzie arrjest tablicą wbudowaną.


0

metoda sortowania bez 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;
        }
    }
}

Uruchom pełny przykład:

#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
Naprawdę? Chcesz użyć powolnego sortowania bąbelkowego zamiast standardowej biblioteki? Nie tylko to, masz jeden błąd powodujący UB.
Mark Ransom

-1

możesz użyć,

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

Cześć, to pytanie wydaje się już mieć szeroko akceptowaną odpowiedź. Czy możesz wyjaśnić, czym to się różni?
Stefan

Tablice nie mają begini endmetod. Musisz myśleć o vector.
Mark Ransom
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.