C ++ 'da bir diziyi sıralamak için std :: sort nasıl kullanılır


91

std::sort()Olarak bildirilen bir diziyi sıralamak için standart şablon kitaplığı nasıl kullanılır int v[2000];

C ++, bir dizinin başlangıç ​​ve bitiş dizinini alabilen bir işlev sağlar mı?

Yanıtlar:


111

C ++ 0x / 11 elde ederiz std::beginve std::endhangi diziler için aşırı yüklü:

#include <algorithm>

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

C ++ 0x'e erişiminiz yoksa, bunları kendiniz yazmak zor değildir:

// 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
Are std::begin()ve std::end()C ++ 1x eklemeler? Çok iyiler - en başından beri bu şekilde olmalıydı, birçok algoritmayı daha genel hale getirebilirdi!
j_random_hacker

10
std::begin()ve std::end()mevcut C ++ Standardının bir parçası değildir, ancak boost::begin()ve kullanabilirsiniz boost::end().
Kirill V. Lyadvinsky

1
Yorumlara göre düzenlenmiştir.
Xeo

2
Sadece bir hatırlatma: onlar C ++ 11 için önerilen edildi çok önce, çoğumuz bu tür a vardı beginve endbizim kişisel bir araç kitleri işlevini kullanın. Bununla birlikte, C ++ 11'den önce, ciddi bir dezavantajları vardı: integral sabit bir ifadeyle sonuçlanmıyorlardı. Bu nedenle, belirli ihtiyaçlara bağlı olarak, onları veya ikisini bölen bir makro kullanırdık sizeof.
James Kanze

1
@Xeo Ne dediğini anladığımdan emin değilim. decltypekesinlikle belirli kullanımları basitleştirir, ancak ücretsiz beginve endişlevlerle ne ilgisi olduğunu anlamıyorum . (Ve bunlardan biri C stili diziler ve diğeri konteynerler için olmak üzere ikisine sahip olmalısınız, otomatik ayrımcılık sayesinde, türünün bir kap mı yoksa C stili bir dizi mi olduğunu bilmeden bunları şablonlarda kullanabilirsiniz.)
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); 

Gelen C ++ 11 :

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

5
+1: Doğru ama çok kırılgan. Sıralama beyana yakın değilse, bakım sırasında kolayca kırılabilir.
Martin York

1
@Martin: doğru. Bu yüzden kullanmayı tercih ediyorum std::vector. std::vector<int> v(2000); std::sort( v.begin(), v.end() );
Kodum

2
Tabii ki, değişmez dizi boyutlarını kullanmak, örnekte olduğu gibi her zaman tehlikelidir. Ancak dizi boyutunu bir 'sabit int' içine koymakta yanlış bir şey yoktur.
Kai Petzke

31

Boyutu bilmiyorsanız şunları kullanabilirsiniz:

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

Boyutu bilseniz bile, dizinin boyutu daha sonra değiştirilirse hata olasılığını azaltacağı için bu şekilde kodlamak iyi bir fikirdir.


3
Statik olarak ayrılmışsa, boyutu bilmelidir, çünkü derleyici bilir. Ancak bu daha iyi bir kodlama uygulamasıdır.
Benoit

7
Gelecekteki ispat kodunu yazdığınız için, sizeof x/sizeof *xhile kullanmak yerine daha güvenli bir şablon kullanmalısınız: template <typename T, int N> int array_size( T (&)[N] ) { return N; }çünkü bir dizi yerine bir işaretçi iletirseniz bu başarısız olur. Gerekirse bir derleme zaman sabitine dönüştürülebilir, ancak bir yorumda okumak biraz fazla zorlaşır.
David Rodríguez - dribeas

1
@ David: İyi bir fikir, ama daha iyi (ve cesaret ı Hakkı söylemek) yolu tanımlamaktır begin()ve end()fonksiyon diziler dahil tüm ortak konteyner türleri için uzman şablonlar ve bunun yerine bunları kullanın. Xeo'nun cevabı, bunların C ++ 'ya zaten eklendiğini düşündürdü, şimdi öyle görünüyor ... İnsanların başka ne söyleyeceklerine bakacağım ve sonra güncelleyeceğim.
j_random_hacker

1
:) Ben de dahil olmak üzere bu gibi birkaç bit vardır küçük bir yardımcı başlığa sahip begin, end, size, STATIC_SIZE, ama dürüst olmak gerekirse, ben neredeyse hiç küçük kod örnekleri o dışını kullanma (döner boyutu ile bir derleme zamanı sabiti olduğu makro).
David Rodríguez - dribeas

1
Bir dizinin boyutu tarafından std::extent<decltype(v)>::valueC ++ 11
xis

18

Sıralayabilirsin std::sort(v, v + 2000)


4
+1: Doğru ama çok kırılgan. Sıralama beyana yakın değilse, bakım sırasında kolayca kırılabilir.
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

sort () C ++ STL'de kullanabilirsiniz. sort () işlevi Sözdizimi:

 sort(array_name, array_name+size)      

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

2

Bu kadar basit ... C ++ size STL (Standart Şablon Kitaplığı) adı verilen sortve elle kodlanmış hızlı sıralamadan% 20 ila% 50 daha hızlı çalışan bir işlev sağlıyor .

İşte kullanımı için örnek kod:

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

1

Sıralama işlevini kullanarak C ++ sıralama

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

vector <int> v[100];

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

Bu, eski sürümde çalışır. Bununla denedim:std::sort(arr, arr + arr_size)
Code Cooker

Bu hiç çalışmıyor. C ++ olmadığını söylemem.
LF

1

C ++ std::sortişlevini kullanın :

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

Stack Overflow'a hoş geldiniz. Herhangi bir açıklama olmaksızın yalnızca kod sağlayan yanıtlar genellikle hoş karşılanmaz, özellikle a) zaten verilmiş birçok yanıt varsa ve b) bir yanıt zaten kabul edilmişse. Lütfen çözümünüzün neden halihazırda yayınlanan 12 çözümden farklı ve / veya daha iyi olduğunu açıklayın.
chb

1

C ++ 20 ile gelen Ranges kitaplığı ile şunları kullanabilirsiniz:

ranges::sort(arr);

doğrudan, arryerleşik bir dizi nerede .


0

olmadan sıralama yöntemi 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;
        }
    }
}

Tam örnek çalıştırın :

#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
Gerçekten mi? Standart kitaplık yerine yavaş balon sıralaması mı kullanmak istiyorsunuz? Sadece bu değil, UB'ye neden olan bir defaya mahsus bir hatanız var.
Mark Ransom

-1

kullanabilirsiniz,

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

Merhaba, bu sorunun zaten genel kabul görmüş bir cevabı var gibi görünüyor. Bunun nasıl farklı olduğunu açıklayabilir misin?
Stefan

Dizilerin beginve endyöntemleri yoktur. Bir vector.
Mark Ransom
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.