Cara menggunakan std :: sort untuk mengurutkan larik di C ++

91

Bagaimana menggunakan pustaka template standar std::sort()untuk mengurutkan array yang dideklarasikan sebagai int v[2000];

Apakah C ++ menyediakan beberapa fungsi yang bisa mendapatkan indeks awal dan akhir dari sebuah array?

Varaquilex
sumber

Jawaban:

111

Di C ++ 0x / 11 kita mendapatkan std::begindan std::endyang kelebihan beban untuk array:

#include <algorithm>

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

Jika Anda tidak memiliki akses ke C ++ 0x, tidak sulit untuk menulisnya sendiri:

// 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;
}
Xeo
sumber
12
Apakah std::begin()dan std::end()C ++ 1x tambahan? Mereka sangat bagus - seharusnya seperti ini sejak awal, itu akan membuat banyak algoritme menjadi lebih umum!
j_random_hacker
10
std::begin()dan std::end()bukan bagian dari Standar C ++ saat ini, tetapi Anda dapat menggunakan boost::begin()dan boost::end().
Kirill V. Lyadvinsky
1
Diedit sesuai dengan komentar.
Xeo
2
Sekadar pengingat: jauh sebelum mereka diusulkan untuk C ++ 11, kebanyakan dari kita memiliki fungsi begindan seperti itu enddi kit alat pribadi kita. Sebelum C ++ 11, bagaimanapun, mereka memiliki kelemahan serios: mereka tidak menghasilkan ekspresi konstan yang tidak terpisahkan. Jadi tergantung pada kebutuhan spesifik, kami akan menggunakannya, atau makro yang melakukan pembagian keduanya sizeof.
James Kanze
1
@Xeo Saya tidak yakin saya mengerti apa yang Anda katakan. decltypetentu saja menyederhanakan penggunaan tertentu, tetapi saya tidak melihat apa hubungannya dengan free beginand endfunctions. (Dan Anda benar-benar harus memiliki dua di antaranya, satu untuk larik gaya C, dan satu lagi untuk penampung, dengan diskriminasi otomatis, sehingga Anda dapat menggunakannya dalam templat, tanpa mengetahui apakah tipenya adalah penampung atau larik gaya 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); 

Di C ++ 11 :

#include <algorithm>
#include <array>
std::array<int, 2000> v;
// Fill the array by values
std::sort(v.begin(),v.end()); 
Naszta
sumber
5
+1: Benar tapi sangat rapuh. Jika jenis tidak dekat dengan deklarasi ini dapat dengan mudah rusak selama pemeliharaan.
Martin York
1
@Artin: benar. Itu sebabnya saya lebih suka menggunakan std::vector. Kode saya adalah:std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Naszta
2
Tentu saja, menggunakan ukuran larik literal selalu berbahaya, seperti pada contoh. Tapi tidak ada yang salah dengan meletakkan ukuran array menjadi 'const int'.
Kai Petzke
31

Jika Anda tidak mengetahui ukurannya, Anda dapat menggunakan:

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

Bahkan jika Anda mengetahui ukurannya, ada baiknya untuk mengkodekannya dengan cara ini karena akan mengurangi kemungkinan bug jika ukuran array diubah nanti.

j_random_hacker
sumber
3
Jika dialokasikan secara statis, ia harus mengetahui ukurannya, karena kompilator tahu. Tapi ini adalah praktik pengkodean yang lebih baik.
Benoit
7
Karena Anda menulis kode bukti masa depan, alih-alih menggunakan sizeof x/sizeof *xtrik, Anda harus menggunakan templat yang lebih aman:, template <typename T, int N> int array_size( T (&)[N] ) { return N; }karena itu akan gagal jika alih-alih larik Anda meneruskan penunjuk. Ini dapat diubah menjadi konstanta waktu kompilasi jika diperlukan, tetapi menjadi agak terlalu sulit untuk dibaca dalam komentar.
David Rodríguez - dribeas
1
@David: Ide bagus, tetapi cara yang lebih baik (dan berani saya katakan The Right) adalah dengan mendefinisikan begin()dan end()menjalankan template yang dikhususkan untuk semua jenis wadah umum, termasuk array, dan menggunakannya sebagai gantinya. Jawaban Xeo membuat saya berpikir ini telah ditambahkan ke C ++, sekarang sepertinya belum ... Saya akan melihat apa lagi yang orang katakan dan kemudian perbarui.
j_random_hacker
1
:) Saya memiliki header utilitas kecil yang memiliki beberapa bit seperti ini, termasuk begin, end, size, STATIC_SIZE(makro yang kembali kompilasi waktu yang konstan dengan ukuran), tapi jujur, saya hampir tidak pernah menggunakan di luar contoh kode kecil.
David Rodríguez - dribeas
1
Ukuran array dapat diterima std::extent<decltype(v)>::valuedalam C ++ 11
xis
18

Anda bisa mengurutkannya std::sort(v, v + 2000)

Mayank
sumber
4
+1: Benar tapi sangat rapuh. Jika jenis tidak dekat dengan deklarasi ini dapat dengan mudah rusak selama pemeliharaan.
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;
    }


}
Wahid Butt
sumber
2

Anda dapat menggunakan sort () di C ++ STL. sort () function Sintaks:

 sort(array_name, array_name+size)      

 So you use  sort(v, v+2000);
ruam
sumber
2

Ini sesederhana itu ... C ++ menyediakan Anda sebuah fungsi dalam STL (Standard Template Library) yang disebut sortyang berjalan 20% hingga 50% lebih cepat daripada quick-sort yang dikodekan dengan tangan.

Berikut adalah contoh kode penggunaannya:

std::sort(arr, arr + size);
risheek reddy
sumber
1

Penyortiran C ++ menggunakan fungsi sortir

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

vector <int> v[100];

int main()
{
  sort(v.begin(), v.end());
}
Mahedi Hasan Durjoy
sumber
Yang ini Bekerja pada versi yang lebih lama. Saya mencoba dengan ini:std::sort(arr, arr + arr_size)
Code Cooker
Ini tidak bekerja sama sekali. Bukan berarti itu bukan C ++.
LF
1

Gunakan fungsi C ++ std::sort:

#include <algorithm>
using namespace std;

int main()
{
  vector<int> v(2000);
  sort(v.begin(), v.end());
}
Toby Speight
sumber
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;
}
pengguna5465465465
sumber
Selamat datang di Stack Overflow. Jawaban yang hanya memberikan kode, tanpa penjelasan apa pun, umumnya tidak disukai, terutama jika a) jawaban sudah banyak tersedia, dan b) jawaban sudah diterima. Harap jelaskan mengapa solusi Anda berbeda dan / atau lebih baik dari 12 solusi yang telah diposting.
chb
1

Dengan perpustakaan Ranges yang datang dalam C ++ 20, Anda dapat menggunakan

ranges::sort(arr);

secara langsung, di mana arrarray bawaan.

LF
sumber
0

metode penyortiran tanpa 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;
        }
    }
}

Jalankan contoh lengkap:

#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;
}
pengguna6021501
sumber
1
Betulkah? Anda ingin menggunakan jenis gelembung lambat daripada pustaka standar? Tidak hanya itu, Anda mengalami error off-by-one yang menyebabkan UB.
Markus Tebusan
-1

kamu bisa memakai,

 std::sort(v.begin(),v.end());
Rohit Hajare
sumber
Hai, pertanyaan ini sepertinya sudah memiliki jawaban yang diterima secara luas. Bisakah Anda menjelaskan bagaimana ini berbeda?
Stefan
Array tidak memiliki begindan endmetode. Anda pasti memikirkan a vector.
Mark Ransom