std :: sortを使用してC ++で配列をソートする方法


90

標準テンプレートライブラリを使用std::sort()してint v[2000]、として宣言された配列をソートする 方法。

C ++は、配列の開始インデックスと終了インデックスを取得できる関数を提供していますか?

回答:


109

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 '

10
std::begin()およびstd::end()は現在のC ++標準の一部ではありませんが、boost::begin()およびを使用できますboost::end()
キリルV.リャドビンスキー

1
コメントに応じて編集。
Xeo

2
覚えておくべきこと:彼らがC ++ 11に提案されるずっと前に、私たちのほとんどはそのようなa beginend機能を私たちの個人用ツールキットに持っていました。ただし、C ++ 11より前のバージョンには、重大な欠点がありました。整数定数式にはなりませんでした。したがって、特定のニーズに応じて、それらを使用するか、2つを分割したマクロを使用しますsizeof
James Kanze、

1
@Xeo何を言っているのかよくわかりません。 decltype確かに特定の用途を単純化しますが、それがfree beginendfunctions とどう関係しているかはわかりません。(そして、実際には、それぞれがCスタイル配列用とコンテナー用に2つずつあり、自動判別により、タイプがコンテナーであるかCスタイル配列であるかを知らなくても、テンプレートで使用できます。)
ジェームズ・カンゼ

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

2
もちろん、例のように、リテラル配列サイズを使用することは常に危険です。しかし、配列サイズを「const int」に入れることには何の問題もありません。
カイペツケ2013

31

サイズがわからない場合は、以下を使用できます。

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

サイズがわかっている場合でも、配列のサイズが後で変更された場合にバグが発生する可能性を減らすため、この方法でコーディングすることをお勧めします。


3
静的に割り当てられている場合は、コンパイラが知っているため、サイズを知っている必要があります。しかし、これはより良いコーディング方法です。
Benoit、

7
将来の証明コードを記述しているので、sizeof x/sizeof *xトリックを使用する代わりに、より安全なテンプレートを使用する必要があります:template <typename T, int N> int array_size( T (&)[N] ) { return N; }配列の代わりにポインターを渡すと失敗します。必要に応じてコンパイル時定数に変換できますが、コメントを読み取るのが少し難しくなります。
デビッドロドリゲス-11

1
@David:良いアイデアですが、さらに良い(そしてあえて言うなら、正しい)方法は、配列を含むすべての一般的なコンテナータイプに特化したテンプレートを定義begin()してend()機能させ、代わりに使用することです。Xeoの回答から、これらはすでにC ++に追加されていると思いましたが、まだ追加されていないようです...他の人が言っていることを確認してから更新します。
j_random_hacker '

1
:)私には、このようないくつかのビットを有し、小さなユーティリティヘッダ有しbeginendsizeSTATIC_SIZE(サイズがコンパイル時定数を返すマクロ)が、正直に言うと、私はほとんどない小さなコードサンプルの外側を使用します。
デビッドロドリゲス-11

1
配列のサイズはstd::extent<decltype(v)>::valueC ++ 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

sort関数を使用した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)
コードクッカー

これはまったく機能しません。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へようこそ。特にa)すでに多くの回答が提供されており、かつb)回答がすでに受け入れられている場合は、説明なしでコードのみを提供する回答は一般に嫌われます。あなたのソリューションが、すでに投稿されている12のソリューションと異なる、および/または優れている理由を詳しく説明してください。
1

1

それはそれと同じくらい簡単です... C ++はSTL(Standard Template Library)で呼び出される関数を提供します。この関数は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の原因となる1つずれるエラーが発生します。
Mark Ransom 2017年

-1

使用できます

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

こんにちは、この質問にはすでに広く受け入れられている答えがあるようです。これがどのように違うのか説明できますか?
Stefan

配列にはbeginand endメソッドはありません。あなたは考えている必要がありますvector
Mark Ransom 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.