如何使用std :: sort在C ++中对数组进行排序


90

如何使用标准模板库std::sort()对声明为的数组进行排序 int v[2000]

C ++是否提供一些可以获取数组的开始和结束索引的函数?

Answers:


109

在C ++ 0x / 11中,我们得到std::beginstd::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 2011年

10
std::begin()并且std::end()不是当前C ++标准的一部分,但是您可以使用boost::begin()boost::end()
2011年

1
对评论进行了相应的编辑。
Xeo

2
提醒一下:在为C ++ 11提出建议之前,我们大多数人在我们的个人工具包中都具有这样的beginend功能。但是,在C ++ 11之前,它们具有严重的缺点:它们没有导致整数常量表达式。因此,根据具体需要,我们将使用它们,或者使用将两者相除的宏sizeof
James Kanze 2011年

1
@Xeo我不确定我是否理解您的意思。 decltype当然可以简化某些用途,但是我不知道它与free beginendfunction 有什么关系。(并且您确实应该分别使用自动识别的两个样式,一个用于C样式数组,另一个用于容器,因此您可以在模板中使用它们,而无需知道类型是容器还是C样式数组。)
詹姆斯·坎泽(James Kanze)2011年

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

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() );
纳斯塔2011年

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; },因为如果传递指针而不是数组,则该模板将失败。如果需要,可以将其转换为编译时间常数,但在注释中变得有点难以阅读。
大卫·罗德里格斯(DavidRodríguez)-dribeas,2011年

1
@David:好主意,但更好的方法(敢于我说对了)是定义begin()end()运行专门用于所有常见容器类型(包括数组)的模板,而改用它们。Xeo的回答使我觉得这些已经添加到C ++中,现在看来它们还没有。
j_random_hacker 2011年

1
:)我有了这样的,包括几个比特的小工具头beginendsizeSTATIC_SIZE(宏收益与规模编译时间常数),但说实话,我很少使用小代码样本的那个之外。
大卫·罗德里格斯(DavidRodríguez)-dribeas 2011年

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

您可以在C ++ STL中使用sort()。sort()函数语法:

 sort(array_name, array_name+size)      

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

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

欢迎使用堆栈溢出。通常仅提供不带任何解释的代码的答案就被打乱了,特别是当a)已经提供了很多答案,并且b)答案已经被接受时。请详细说明为什么您的解决方案与已发布的12种解决方案不同和/或更好。
chb

1

就这么简单... C ++在STL(标准模板库)中为您提供了一个函数,该函数的sort运行速度比手动编码的快速排序快20%至50%。

这是其用法的示例代码:

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

1

使用C ++ 20中随附的Ranges库,您可以使用

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的错误错误。
Mark Ransom'1

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.