STL - sort (2) (펌)

2019. 1. 14. 18:39IT-개발/STL 및 Boost

반응형



Sort 함수  이런걸 define으로 그냥 쓸까 고민하다가


  1. #define MAX(a,b) \  
  2. ({ __typeof__ (a) _a = (a); \  
  3. __typeof__ (b) _b = (b); \  
  4. _a > _b ? _a : _b; })  
  5.   
  6. #define MIN(a,b) \  
  7. ({ __typeof__ (a) _a = (a); \  
  8. __typeof__ (b) _b = (b); \  
  9. _a < _b ? _a : _b; }) 


STL sort가 data Type에 상관없이 쓸수 있는거 같아서 역시 퍼놓습니다.


Pair 같은 것에 대해서 기본적으로 sort를 제공해주는게 참 좋네요. pair에 대해서도 재정의를 해야 되나 싶어서


고민했는데~ ㅎㅎ~ 다행~ 한번씩 참고~




(펌 : https://www.acmicpc.net/blog/view/22)


STL sort 튜토리얼


1. 정의

알고리즘 헤더파일에서 제공하는 STL로써 범위내에서 주어진 범위내에서 원소들을 정렬합니다. 이때 정렬하는 방식(오름차순, 내림차순 등등등)은 사용자가 정의할 수 있으며, 동일한 원소에 대해서는 그 순서가 보장되지 않습니다. 이때 std::sort는 숫자 뿐만 아니라 대소 비교가 가능한 모든 원소에 대해서 정렬을 할 수 있습니다. 즉 int 뿐만 아니라 char, string 역시 정렬이 가능하고, 사용자가 정의한 객체 역시 연산자 오버로딩('<')을 정의해주면 정렬이 가능합니다. 또한 동일한 원소에 대해서 그 원소들의 상대적 순서를 보장해 주는 라이브러리도 존재합니다.

자세한 내용은 여기를 참고해 주세요.

2. 특징

2개의, 혹은 3개의 argument를 필요로 하는데, 첫번째 두개의 argument는 iterator로써 정렬하는 범위를 나타냅니다. 이때 iterator는 random access와, 수정이 가능해야 합니다. 기본적으로 Strick week Ordering, 즉 두개의 객체를 비교해서 첫번째가 두번째보다 작으면 true 그렇지 않다면 false를 리턴합니다. 대부분 quick sort를 사용한다고 알려져 있지만 대부분의 컴파일러에서 다양한 방식의 정렬을 복합적으로 사용합니다. GCC의 경우 introsort와 원소의 개수가 적을 경우 insertion sort를 사용한다고 알려져 있습니다.

자세한 내용은 여기를 참고해 보세요.

3. 사용법

기본 사용법

template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

배열 정렬

기본적으로 std::sort를 이용하면 오름차순 정렬이 수행됩니다.

소스예제

#include <iostream>
#include <algorithm>

using namespace std;

int main(){

    int arr[5];
    arr[0] = 0;
    arr[1] = 4;
    arr[2] = 3;
    arr[3] = 1;
    arr[4] = 5;
    sort(arr, arr + 5);

    for (int i = 0; i < 5; i++)
        cout << arr[i] << endl;

    return 0;
}

결과

0
1
3
4
5

정렬 오름차순(greater)

내림차순 정렬을 수행하기 위해서 fuctional 헤더에서 제공하는 less를 사용하는 방법입니다.

소스예제

#include <iostream>
#include <functional>
#include <algorithm>

using namespace std;

int main(){
    int arr[5];
    arr[0] = 0;
    arr[1] = 4;
    arr[2] = 3;
    arr[3] = 1;
    arr[4] = 5;

    sort(arr, arr + 5, greater<int>());

    for (int i = 0; i < 5; i++)
        cout << arr[i] << endl;

    return 0;
}

결과

5
4
3
1
0

vector의 정렬

숫자 뿐만 아니라 대소비교가 가능한 모든 변수형은 정렬이 가능합니다.

소스예제

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(){
    vector<char> v;
    v.push_back('c');
    v.push_back('b');
    v.push_back('e');
    v.push_back('a');
    v.push_back('g');

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

    for (int i = 0; i < 5; i++)
        cout << v[i] << endl;

    return 0;
}

결과

a
b
c
e
g

사용자 정의 객체 정렬 (global < operator)

연산자 오버로딩을 통해서 사용자 정의 객체를 정렬해 봅시다.

소스예제

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class Person{
public:
    string name;
    int age;
    Person(string name, int age){
        this->name = name;
        this->age = age;
    }
};

bool operator <(const Person &a, const Person &b){
    return a.age < b.age;
}

int main(){
    vector<Person> v;
    v.push_back(Person("MinJi", 22));
    v.push_back(Person("Kangho", 28));
    v.push_back(Person("Minho", 26));
    v.push_back(Person("Strange Yun", 25));
    sort(v.begin(), v.end());
    for (int i = 0; i < v.size(); i++)
        cout << v[i].age  << ", " <<  v[i].name << endl;

}

결과

22, MinJi
25, Strange Yun
26, Minho
28, Kangho

객체 정렬 (클래스내 연산자 오버로딩)

소스예제

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class Person{
public:
    string name;
    int age;
    Person(string name, int age){
        this->name = name;
        this->age = age;
    }
    bool operator <(const Person &a) const {
        return this->age < a.age;
    }

};

int main(){
    vector<Person> v;
    v.push_back(Person("MinJi", 22));
    v.push_back(Person("Kangho", 28));
    v.push_back(Person("Minho", 26));
    v.push_back(Person("Strange Yun", 25));
    v.push_back(Person("JunEun", 40));
    sort(v.begin(), v.end());
    for (int i = 0; i < v.size(); i++)
        cout << v[i].age  << ", " <<  v[i].name << endl;

}

결과

22, MinJi
25, Strange Yun
26, Minho
28, Kangho
40, JunEun

객체 정렬 (사용자 정의 함수)

이름을 기준으로 내림차순 정렬하는 사용자 정의 함수를 작성해봅니다.

예제소스

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class Person{
public:
    string name;
    int age;
    Person(string name, int age){
        this->name = name;
        this->age = age;
    }
};

bool cmp(const Person &a, const Person &b){
    return a.name > b.name;
}

int main(){
    vector<Person> v;
    v.push_back(Person("Ace", 22));
    v.push_back(Person("Luffy", 28));
    v.push_back(Person("Zoro", 26));
    v.push_back(Person("Robin", 25));
    v.push_back(Person("Brook", 40));
    sort(v.begin(), v.end(), cmp);
    for (int i = 0; i < v.size(); i++)
        cout << v[i].age  << ", " <<  v[i].name << endl;
}

결과

26, Zoro
25, Robin
28, Luffy
40, Brook
22, Ace

STL Pair의 정렬

많이 쓰이는 STL의 pair을 sort함수로 정렬할 경우 기본적으로 pair의 첫번째 원소를 기준으로 정렬이 되고 첫번째 원소가 같을 경우 두번째 원소를 사용해서 비교하게 됩니다.

예제소스

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

int main(){
    vector<pair<int, string> > v;
    v.push_back(pair<int, string>(20, "A_Jiwoo"));
    v.push_back(pair<int, string>(21, "B_Songju"));
    v.push_back(pair<int, string>(21, "C_Induk"));
    v.push_back(pair<int, string>(21, "D_SeungHyun"));
    v.push_back(pair<int, string>(20, "E_Soyen"));

    sort(v.begin(), v.end());
    for (int i = 0; i < v.size(); i++)
        cout << v[i].first  << ", " <<  v[i].second << endl;

}

결과

20, A_Jiwoo
20, E_Soyen
21, B_Songju
21, C_Induk
21, D_SeungHyun