이 주제는 C++ STL 의 기본에 가까운 듯 한데,
평소에 C++ 로 프로젝트가 진행되는 경우가 없어서 익숙하지가 않아,
쓸때마다 헷갈려서 ( 특히 object pointer 타입을 다룰 때... ) 정리차원에서 한 번 포스팅해 봄.
1. primitive 타입
먼저 가장 기본 형태. primitive type 의 vector 를 보자.
vector<int> v;
for (int i = 0; i < 20; i++)
v.push_back(i);
random_shuffle(v.begin(), v.end());
for (int i = 0; i < 20; i++) cout << v[i] << " ";
cout << endl;
sort(v.begin(), v.end());
for (int i = 0; i < 20; i++) cout << v[i] << " ";
cout << endl;
(실행결과)
1 11 15 0 14 7 16 13 8 10 17 5 2 19 18 9 4 3 6 12
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
위와 같이 오름차순으로 정렬이 된다.
기본적으로 std::sort 함수는 elements 비교에 '<' 연산자를 사용하기 때문이다.
그럼 내림차순으로 정렬을 하려면 어떻게 해야 하는가?
바로 compare 하는 함수를 지정해 주거나, compare object 를 지정해 주는 것이다.
이때 함수는 bool comp(int a, int b) 형태로 표현하면 된다.
중요한 점은 comp 함수의 return value 가 true 라면 a 가 b 보다 앞으로 간다는 것이다.
위의 코드에서 comp 함수를 추가하고 sort 를 아래와 같이 바꿔서 실행해 보면
// compare function
bool comp(int a, int b) {
return (a > b);
}
// compare object
struct comp_object {
bool operator() (int a, int b) {
return (a > b);
};
} comp_obj;
.
.
.
sort(v.begin(), v.end(), comp);
sort(v.begin(), v.end(), comp_obj);
(실행결과)
1 11 15 0 14 7 16 13 8 10 17 5 2 19 18 9 4 3 6 12
19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
위와같이 내림차순으로 정렬이 된다.
( compare object 에 대해서는 나도 잘 알지 못하기에 뒤의 class T, class T* 타입에 대한 내용에서는 패스한다.)
2. Class T 타입
이제 본격적으로 vector<class T> 타입의 정렬에 대해서 알아보자.
기본 사용법은 아래와 같다. 위에서 언급하였듯이 std::sort 는 elements 비교에
'<' 연산자를 사용하므로 '<' 연산자를 오버로딩 해 주어야 한다.
class T {
public:
int data;
T (int a) { data = a; }
bool operator<(const T &t) const {
return (data < t.data);
}
};
vector<T> v;
for (int i = 0; i < 20; i++) {
v.push_back(T(i));
}
random_shuffle(v.begin(), v.end());
for (int i = 0; i < 20; i++) cout << v[i].data << " ";
cout << endl;
sort(v.begin(), v.end());
for (int i = 0; i < 20; i++) cout << v[i].data << " ";
cout << endl;
(실행결과)
17 2 15 14 0 3 1 9 5 10 8 7 18 19 11 16 6 13 12 4
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
'<' 연산자는 sort 뿐만 아니라 다른 코드에서도 사용할 수 있으므로,
'<' 연산결과와 다른 순서로 sorting 을 하고 싶다면,
compare 함수를 직접 지정해 주면 된다.
class T {
public:
int data;
T (int a) { data = a; }
bool operator<(const T &t) const {
return (data < t.data);
}
static bool comp(const T &t1, const T &t2) {
return (t1.data > t2.data);
}
};
.
.
.
sort(v.begin(), v.end(), T::comp);
물론 comp 함수가 class T 의 멤버함수일 필요는 없다.
( 하지만 더 깔끔해 보이지 않은가? )
3. Class T* 타입
(중요) T* 타입은 class 의 '<' 연산자 오버로딩을 하여도 제대로 동작하지 않는다!!!
게다가 아래와 같은 코드가 함께 있다면,
bool operator<(const T &t) const { ... }
빌드 에러도 발생하지 않는다.
가령 위의 코드에서 T 의 멤버함수에 아래와 같이 연산자 오버로딩을 하고,
bool operator<(const T *t) const {
return(data < t->data);
}
vector<T*> 에 대해서 std::sort 수행하여도 저 함수는 호출되지 않는다.
vector<T*> 에 대하여 std::sort 를 하기 위해서는,
T* 에 대한 compare fuction 이나 compare object 를 지정해 주어야 한다.
class T {
public:
int data;
T (int a) { data = a; }
static bool comp(const T *t1, const T *t2) {
return (t1->data < t2->data);
}
};
.
.
.
sort(v.begin(), v.end(), T::comp);
쓰다보니 가장 중요한 내용이 제일 마지막에 있게 되었는데, 잘 기억해 두자.
'CPP' 카테고리의 다른 글
STL 정렬 (0) | 2015.12.23 |
---|---|
모듈 이 safeseh 이미지 에 대해 안전 하지 않습니다 (0) | 2014.10.01 |
싱글톤 2 (0) | 2014.09.30 |
싱글톤 패턴 (Singleton Pattern) (1) | 2014.09.29 |