Як використовувати std :: sort для сортування масиву в C ++


91

Як використовувати стандартну бібліотеку шаблонів std::sort()для сортування масиву, оголошеного як int v[2000];

Чи надає С ++ якусь функцію, яка може отримати індекс початку та кінця масиву?

Відповіді:


111

У C ++ 0x / 11 ми отримуємо std::beginі std::endякі перевантажені для масивів:

#include <algorithm>

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

Якщо у вас немає доступу до C ++ 0x, не складно написати їх самостійно:

// 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
Чи є доповнення std::begin()та std::end()C ++ 1x? Вони дуже симпатичні - це мало бути з самого початку, це зробило б багато алгоритмів загальнішими!
j_random_hacker

10
std::begin()і std::end()не є частиною поточного стандарту C ++, але ви можете використовувати boost::begin()і boost::end().
Кирило Васильович Лядвінський

1
Відредаговано відповідно до коментарів.
Xeo

2
Тільки нагадуємо: задовго до того, як вони запропонували для C ++ 11, більшість із нас мали такі функції beginта endфункції в наших особистих наборах інструментів. Однак до С ++ 11 вони мали серйозний недолік: вони не дали цілісного постійного виразу. Отже, залежно від конкретних потреб, ми б їх використовували, або макрос, який здійснив розподіл двох sizeof.
Джеймс Канце,

1
@Xeo Я не впевнений, що розумію, що ти кажеш. decltypeбезумовно спрощує певне використання, але я не розумію, яке відношення це має до безкоштовних beginта endфункцій. (І ви дійсно повинні мати по два з них, один для масивів стилю C, а інший для контейнерів, з автоматичною дискримінацією, щоб ви могли використовувати їх у шаблонах, не знаючи, тип є контейнером або масивом стилю 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); 

У C ++ 11 :

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

5
+1: Правильний, але дуже крихкий. Якщо сортування не біля декларації, це може бути легко порушено під час технічного обслуговування.
Мартін Йорк,

1
@Martin: правда. Ось чому я волію використовувати std::vector. Мій код буде:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Нашта

2
Звичайно, використання буквальних розмірів масивів завжди небезпечно, як у прикладі. Але немає нічого поганого в тому, щоб розмістити масив у "const int".
Kai Petzke

31

Якщо ви не знаєте розмір, ви можете використовувати:

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

Навіть якщо ви знаєте розмір, непогано кодувати його таким чином, оскільки це зменшить можливість помилки, якщо розмір масиву буде змінено пізніше.


3
Якщо він виділений статично, він повинен знати розмір, оскільки компілятор знає. Але це краща практика кодування.
Бенуа

7
Оскільки ви пишете майбутній код перевірки, замість того, щоб використовувати sizeof x/sizeof *xфокус, ви повинні використовувати безпечніший шаблон:, template <typename T, int N> int array_size( T (&)[N] ) { return N; }оскільки це не вдасться, якщо замість масиву ви передасте вказівник. За необхідності його можна перетворити на постійну часу компіляції, але читати у коментарі стає трохи важко.
Девід Родрігес - дрибі

1
@David: Хороша ідея, але ще кращий (і наважусь сказати Правильний) спосіб полягає у визначенні begin()та end()функціонуванні шаблонів, які спеціалізуються на всіх поширених типах контейнерів, включаючи масиви, та використовують їх замість цього. Відповідь Xeo змусив мене думати, що вони вже були додані до C ++, тепер, здається, не ... Побачу, що ще люди мають сказати, а потім оновлю.
j_random_hacker

1
:) У мене є невелика утиліта заголовок , який має кілька біт , як це, в тому числі begin, end, size, STATIC_SIZE(макросу , який повертає компіляції постійного часу з розміром), але якщо чесно, я навряд чи коли - небудь використовувати , що за межі невеликих зразків коди.
Девід Родрігес - дрибі

1
Розмір масиву можна отримати std::extent<decltype(v)>::valueв C ++ 11
xis

18

Ви можете сортувати std::sort(v, v + 2000)


4
+1: Правильний, але дуже крихкий. Якщо сортування не біля декларації, це може бути легко порушено під час технічного обслуговування.
Мартін Йорк,

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

Ви можете використовувати sort () у C ++ STL. синтаксис функції sort ():

 sort(array_name, array_name+size)      

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

2

Це так просто ... C ++ надає вам функцію в STL (стандартна бібліотека шаблонів), sortяка працює на 20-50% швидше, ніж ручне кодування.

Ось зразок коду для його використання:

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

1

Сортування С ++ за допомогою функції сортування

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

vector <int> v[100];

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

Цей працює на старій версії. Я спробував із цим:std::sort(arr, arr + arr_size)
Code Cooker

Це взагалі не працює. Не сказати, що це не C ++.
LF


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

Ласкаво просимо до Stack Overflow. Відповіді, що містять лише код, без будь-яких пояснень, як правило, не приймаються до уваги, особливо коли а) існує багато відповідей, і б) відповідь уже прийнята. Будь ласка, детальніше поясніть, чому ваше рішення відрізняється та / або краще від 12, які вже були опубліковані.
chb

1

За допомогою бібліотеки Ranges, яка випускається на C ++ 20, ви можете використовувати

ranges::sort(arr);

безпосередньо, де arrє вбудований масив.


0

метод сортування без 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;
        }
    }
}

Запустити повний приклад:

#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
Справді? Ви хочете використовувати повільну сортування міхурів замість стандартної бібліотеки? Мало того, у вас є поодинока помилка, що спричиняє UB.
Марк Ренсом

-1

Ви можете використовувати,

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

Привіт, це питання вже має загальновизнану відповідь. Чи можете ви пояснити, чим це відрізняється?
Стефан

Масиви не мають beginі endметоди. Ви, мабуть, думаєте про a vector.
Марк Ренсом
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.