Cách sử dụng std :: sort để sắp xếp một mảng trong C ++


91

Cách sử dụng thư viện mẫu chuẩn std::sort()để sắp xếp một mảng được khai báo là int v[2000];

C ++ có cung cấp một số hàm có thể lấy chỉ số bắt đầu và kết thúc của một mảng không?

Câu trả lời:


111

Trong C ++ 0x / 11, chúng tôi nhận được std::beginstd::endđược nạp chồng cho các mảng:

#include <algorithm>

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

Nếu bạn không có quyền truy cập vào C ++ 0x, không khó để tự viết chúng:

// 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
Có phải std::begin()std::end()C ++ bổ sung 1x không? Chúng rất đẹp - lẽ ra phải theo cách này ngay từ đầu, nó sẽ khiến nhiều thuật toán trở nên chung chung hơn!
j_random_hacker

10
std::begin()std::end()không phải là một phần của Tiêu chuẩn C ++ hiện tại, nhưng bạn có thể sử dụng boost::begin()boost::end().
Kirill V. Lyadvinsky

1
Đã chỉnh sửa cho phù hợp với các ý kiến.
Xeo

2
Chỉ xin nhắc lại: rất lâu trước khi họ được đề xuất cho C ++ 11, hầu hết chúng ta đều có một beginendchức năng như vậy trong bộ công cụ cá nhân của mình. Tuy nhiên, trước C ++ 11, chúng có một nhược điểm: chúng không dẫn đến một biểu thức hằng tích phân. Vì vậy, tùy thuộc vào nhu cầu cụ thể, chúng tôi sẽ sử dụng chúng hoặc macro đã phân chia hai yếu tố đó sizeof.
James Kanze

1
@Xeo Tôi không chắc mình hiểu bạn đang nói gì. decltypechắc chắn đơn giản hóa một số mục đích sử dụng, nhưng tôi không thấy nó liên quan gì đến các chức năng beginvà miễn phí end. (Và bạn thực sự nên có hai trong số chúng, một cho mảng kiểu C và một cho vùng chứa, với khả năng phân biệt tự động, vì vậy bạn có thể sử dụng chúng trong các mẫu mà không cần biết kiểu đó là vùng chứa hay mảng kiểu 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); 

Trong C ++ 11 :

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

5
+1: Đúng nhưng rất giòn. Nếu sắp xếp không gần khai báo, điều này có thể dễ dàng bị hỏng trong quá trình bảo trì.
Martin York

1
@Martin: đúng. Đó là lý do tại sao tôi thích sử dụng hơn std::vector. Mã của tôi sẽ là:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Naszta

2
Tất nhiên, việc sử dụng kích thước mảng theo nghĩa đen luôn nguy hiểm, như trong ví dụ. Nhưng không có gì sai khi đặt kích thước mảng vào 'const int'.
Kai Petzke

31

Nếu bạn không biết kích thước, bạn có thể sử dụng:

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

Ngay cả khi bạn biết kích thước, bạn nên viết mã theo cách này vì nó sẽ giảm khả năng xảy ra lỗi nếu kích thước mảng được thay đổi sau này.


3
Nếu nó được cấp phát tĩnh, anh ta nên biết kích thước, bởi vì trình biên dịch biết. Nhưng đây là thực hành mã hóa tốt hơn.
Benoit

7
Vì bạn đang viết mã bằng chứng trong tương lai, thay vì sử dụng sizeof x/sizeof *xthủ thuật, bạn nên sử dụng một mẫu an toàn hơn:, template <typename T, int N> int array_size( T (&)[N] ) { return N; }vì điều đó sẽ không thành công nếu thay vì một mảng bạn chuyển một con trỏ. Nó có thể được chuyển đổi thành một hằng số thời gian biên dịch nếu cần, nhưng nó trở nên hơi khó đọc trong một nhận xét.
David Rodríguez - dribeas

1
@David: Ý tưởng hay, nhưng một cách thậm chí còn tốt hơn (và tôi dám nói là Đúng) là xác định begin()end()chức năng các mẫu chuyên biệt cho tất cả các loại vùng chứa phổ biến, bao gồm cả mảng và sử dụng chúng thay thế. Câu trả lời của Xeo khiến tôi nghĩ rằng những thứ này đã được thêm vào C ++, bây giờ có vẻ như chúng chưa ... Tôi sẽ xem những người khác phải nói gì và sau đó cập nhật.
j_random_hacker

1
:) Tôi có một tiêu đề tiện ích nhỏ mà có một vài bit như thế này, bao gồm begin, end, size, STATIC_SIZE(macro lợi nhuận một biên dịch hằng số thời gian với kích thước), nhưng thành thật mà nói, tôi hầu như không bao giờ sử dụng bên ngoài của mẫu mã nhỏ.
David Rodríguez - dribeas

1
Kích thước của một mảng có thể được nhận bởi std::extent<decltype(v)>::valuetrong C ++ 11
xis

18

Bạn có thể sắp xếp nó std::sort(v, v + 2000)


4
+1: Đúng nhưng rất giòn. Nếu sắp xếp không gần khai báo, điều này có thể dễ dàng bị hỏng trong quá trình bảo trì.
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

bạn có thể sử dụng sort () trong C ++ STL. Hàm sort () Cú pháp:

 sort(array_name, array_name+size)      

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

2

Nó đơn giản như vậy ... C ++ cung cấp cho bạn một hàm trong STL (Thư viện mẫu chuẩn) được gọi là hàm sortnày chạy nhanh hơn 20% đến 50% so với sắp xếp nhanh được mã hóa thủ công.

Đây là mã mẫu để sử dụng nó:

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

1

Sắp xếp C ++ bằng cách sử dụng chức năng sắp xếp

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

vector <int> v[100];

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

Cái này hoạt động trên phiên bản cũ hơn. Tôi cố gắng với điều này:std::sort(arr, arr + arr_size)
Mã Bếp

Điều này không hoạt động ở tất cả. Không có nghĩa là nó không phải là C ++.
LF

1

Sử dụng hàm 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;
}

Chào mừng bạn đến với Stack Overflow. Các câu trả lời chỉ cung cấp mã, không có bất kỳ lời giải thích nào, thường không được chấp nhận, đặc biệt là khi a) có nhiều câu trả lời đã được cung cấp và b) một câu trả lời đã được chấp nhận. Vui lòng giải thích tại sao giải pháp của bạn khác và / hoặc tốt hơn so với 12 giải pháp đã được đăng.
chb

1

Với thư viện Ranges sắp có trong C ++ 20, bạn có thể sử dụng

ranges::sort(arr);

trực tiếp, đâu arrlà mảng nội trang.


0

phương pháp sắp xếp mà không có 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;
        }
    }
}

Chạy ví dụ hoàn chỉnh:

#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
Có thật không? Bạn muốn sử dụng sắp xếp bong bóng chậm thay vì thư viện tiêu chuẩn? Không những thế, bạn còn bị lỗi do UB gây ra.
Mark Ransom

-1

bạn có thể dùng,

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

Xin chào, câu hỏi này dường như đã có một câu trả lời được chấp nhận rộng rãi. Bạn có thể giải thích điều này khác nhau như thế nào?
Stefan

Mảng không có beginendphương thức. Chắc hẳn bạn đang nghĩ về a vector.
Mark Ransom
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.