C++에서 제공하는 표준 라이브러리 함수 std::sort는 벡터, 리스트, 배열 등 다양한 컨테이너를 정렬하는 데 사용된다.
1. algorithm 헤더 포함
#include <algorithm>
2. std::sort 함수 원형
template<class RandomIt>
void sort(RandomIt first, RandomIt last);
template<class RandomIt, class Compare>
void sort(RandomIt first, RandomIt last, Compare comp);
- first: 정렬을 시작할 범위의 첫 번째 요소를 가리키는 반복자
- last: 정렬을 종료할 범위의 마지막 다음 요소를 가리키는 반복자
- comp: (optional) 정렬 기준을 제공하는 함수나 함수 객체로 람다식으로 표현될 수 있다
만약 비교함수 comp가 사용자에 의해 제공되지 않은 경우 기본적으로 < 연산자를 사용하여 비교를 수행하며, 이를 통해 오름차순으로 정렬한다.
3. 비교함수 작성
auto compare = [](int a, int b) { return a < b; }
두 요소를 받아들여 비교한 결과를 반환하여 정렬의 순서를 결정하는 비교함수를 작성한다. 비교 함수의 반환값이 양수인 경우 sort함수는 두 요소의 순서를 바꾼다. 위와 같이 람다식을 사용해 인수로 넘겨줄 비교함수를 작성할 수 있다.
보통 정수형 벡터의 경우 오름차순으로 정렬할 때는 return a < b; 내림차순으로 정렬할 때는 return a > b;로 정의하는데 여기서 의문이 생긴다.
a < b가 참일 때 두 요소의 순서가 바뀐다면 큰 수가 앞에 오게되니까 내림차순 정렬되는게 아닌가?
그런데 실제로는 그렇지 않다. 이는 a에 뒷 요소가 들어오기 때문이며 출력을 해보면 이사실을 알 수 있다.
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> numbers = {5, 4, 3, 2, 1};
sort(numbers.begin(), numbers.end(), [](int a, int b) { printf("a: %d, b: %d\n", a, b); return a < b; });
cout << "Sorted numbers in ascending order: ";
for (const auto& num : numbers) {
cout << num << " ";
}
cout << endl;
return 0;
}
- 정수형 벡터 오름차순 정렬 예시
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> numbers = {5, 2, 8, 1, 7, 3};
sort(numbers.begin(), numbers.end());
cout << "Sorted numbers in ascending order: ";
for (const auto& num : numbers) {
cout << num << " ";
}
cout << endl;
return 0;
}
- 람다식으로 비교함수를 정의하여 정수 내림차순 정렬 예시
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> numbers = {5, 2, 8, 1, 7, 3};
sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; });
cout << "Sorted numbers in descending order: ";
for (const auto& num : numbers) {
cout << num << " ";
}
cout << endl;
return 0;
}
- 람다식 비교함수에서 외부 변수를 캡쳐하여 구조체를 정렬하는 예시
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Person {
std::string name;
int age;
};
int main() {
vector<Person> people = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 22}, {"David", 28}};
sort(people.begin(), people.end(), [&](const Person& a, const Person& b) {
return a.age < b.age;
});
cout << "Sorted people with age:" << endl;
for (const auto& person : people) {
cout << person.name << " (" << person.age << ") " << endl;
}
return 0;
}
- 원본 배열을 직접 변경하지 않고 원본 배열의 요소들이 정렬될 순서를 담은 인덱스 배열을 확보하는 예시
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric> // iota 함수를 위해 필요
using namespace std;
int main() {
vector<int> numbers = {5, 2, 8, 1, 7, 3};
vector<int> indices(numbers.size());
// 인덱스 초기화
iota(indices.begin(), indices.end(), 0);
// 인덱스 벡터를 원본 배열의 값에 따라 정렬
sort(indices.begin(), indices.end(), [&numbers](int i1, int i2) {
return numbers[i1] < numbers[i2];
});
cout << "Sorted indices based on the values in the original array: ";
for (int i : indices) {
cout << i << " ";
}
cout << endl;
cout << "Original array sorted based on the sorted indices: ";
for (int i : indices) {
cout << numbers[i] << " ";
}
cout << endl;
return 0;
}
'프로그래밍 > C++' 카테고리의 다른 글
C++ ] std::stack 사용법 (0) | 2024.03.20 |
---|---|
C++ ] std::pair 사용법 (0) | 2024.03.01 |
C++ ] string -> char *, char * -> string 변환 (0) | 2024.02.18 |
C++ 에서 구조체와 클래스의 차이 (0) | 2024.02.14 |
C++ ] 벡터의 최대값과 최소값 찾기, max_element, min_element (0) | 2024.02.10 |