Как использовать 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 05

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

1
Отредактировано в соответствии с комментариями.
Xeo

2
Напоминаем , что задолго до того, что они были предложены для C ++ 11, большинство из нас было такое beginи endфункции в наших личных наборов инструментов. Однако до C ++ 11 у них был серьезный недостаток: они не приводили к целочисленному константному выражению. Поэтому, в зависимости от конкретных потребностей, мы использовали бы их или макрос, который делил эти два элемента sizeof.
Джеймс Канце

1
@Xeo Я не уверен, что понимаю, что вы говорите. decltypeконечно, упрощает некоторые варианты использования, но я не понимаю, какое это имеет отношение к бесплатным beginи endфункциям. (И у вас действительно должно быть по два каждого из них, один для массивов в стиле C, а другой для контейнеров с автоматическим распознаванием, поэтому вы можете использовать их в шаблонах, не зная, является ли тип контейнером или массивом в стиле C.)
Джеймс Канце

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
@ Мартин: правда. Вот почему я предпочитаю использовать std::vector. Мой код будет:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Naszta

2
Конечно, использование буквальных размеров массива всегда опасно, как в примере. Но нет ничего плохого в том, чтобы поместить размер массива в const int.
Кай Петцке

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; }поскольку это не удастся, если вместо массива вы передадите указатель. При необходимости его можно преобразовать в константу времени компиляции, но читать в комментариях становится слишком сложно.
Дэвид Родригес - dribeas

1
@David: Хорошая идея, но даже лучший (и смею сказать правильный) способ - это определить begin()и end()использовать шаблоны, которые специализируются на всех распространенных типах контейнеров, включая массивы, и использовать их вместо них. Ответ Xeo заставил меня подумать, что они уже были добавлены в C ++, теперь кажется, что нет ... Я посмотрю, что еще люди скажут, а затем обновлю.
j_random_hacker 05

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

Сортировка C ++ с использованием функции сортировки

#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методов. Вы, должно быть, думаете о vector.
Марк Рэнсом
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.