[C++, STL] 구조체, pair 벡터 정렬

다른 글

[C++, STL] 알고리즘 문제풀이를 위한 벡터(vector)

[C++, STL] 알고리즘 문제풀이를 위한 pair

서론

벡터에 들어갈 수 있는 자료형에 pair와 struct(구조체)가 있다. 이들을 이용하여 하나의 원소에 다수의 자료가 들어갈 수 있다. pair와 struct를 자료형으로 가지는 벡터에서 사용자 지정 함수를 이용하면 특정 자료를 기준으로 정렬할 수 있다.

pair 벡터 정렬

정수를 자료형으로 갖는 pair의 first를 1차, second를 2차로 오름차순 정렬한다.

정렬전
- first : 3, 1, 1, 2, 3
- second: 4, 1, -1, 2, 3

정렬 후
- first : 1, 1, 2, 3, 3
- second : -1, 1, 2, 3, 4

정렬은 STL의 sort를 이용한다. sort는 정렬의 기준을 정하는 비교함수가 필요하다. first, second 순으로 오름차순 정렬하거나 내림차순 정렬하는것은 STL에 포함되어있는 greater, less를 이용할 수 있고 first는 오름차순인데 second는 내림차순이거나 하는 것들은 직접 비교함수를 구현해야 한다.

greater, less를 이용한 정렬

헤더파일 추가

벡터는 vector, pair는 algorithm 헤더파일에 있다.

네임스페이스는 std이다.

#include <vector>
#include <algorithm>

using namespace std;

벡터 선언

pair를 자료형으로 갖는 vector를 선언한다.

vector<pair<int, int>>v;

정렬 실행

정렬은 STL의 sort를 이용한다. 정렬 범위는 벡터의 begin, end 함수를 사용하며 정렬 조건은 greater, less를 이용한다.

less는 생략이 가능하다.

sort(v.begin(), v.end()); // 오름차순
sort(v.begin(), v.end(), less<>()); // 오름차순
sort(v.begin(), v.end(), greater<>()); // 내림차순

사용자 정의 비교함수를 이용한 정렬

헤더파일 추가

벡터는 vector, pair는 algorithm 헤더파일에 있다.

네임스페이스는 std이다.

#include <vector>
#include <algorithm>

using namespace std;

벡터 선언

pair를 자료형으로 갖는 vector를 선언한다.

vector<pair<int, int>>v;

비교함수 구현

정렬은 STL의 sort를 이용한다. sort는 algorithm 헤더파일에 있다.

sort의 인자로 필요한 비교함수를 구현한다.

bool compare(pair<int, int>a, pair<int, int>b) {
	if (a.first == b.first) {
		return a.second < b.second;
	}
	else {
		return a.first < b.first;
	}
}

정렬을 위해서는 현재 원소와 다음원소의 크기를 비교하고 정해진 비교 규칙에 따라서 둘을 swap 하는 과정이 필요하다. 위 compare 함수에서 a는 현재 원소이고 b는 다음 원소인데, compare의 리턴 값이 false면 swap 한다.

priority_queue의 비교연산자와 swap 조건이 반대인데, 이유를 찾지 못했다.

a와 b의 first 값을 1차로 비교하여 오름차순으로 정렬하고, 만약 두 값이 같다면 second를 2차로 비교하여 오름차순으로 정렬한다. 내림차순으로 정렬하려면 리턴값의 부등호만 반대로 바꾸면 된다.

오름차순 : a.second < b.second

내림차순 : a.second > b.second

정렬 실행

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

전체코드

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool compare(pair<int, int>a, pair<int, int>b) {
	if (a.first == b.first) {
		return a.second < b.second;
	}
	else {
		return a.first < b.first;
	}
}

void init(vector<pair<int, int>> &v){
	v.push_back({3, 4});
	v.push_back({1, 1});
	v.push_back({1, -1});
	v.push_back({2, 2});
	v.push_back({3, 3});
}

int main(){
	vector<pair<int, int>>v;
	init(v);
	sort(v.begin(), v.end(), compare);
	for(auto i : v){
		cout<<i.first<<" "<<i.second<<endl;
	}
}

구조체 벡터 정렬

구조체 s의 score를 기준으로 1차 오름차순 정렬하고, age을 기준으로 2차 오름차순 정렬한다.

정렬 전
- age : 24, 27, 24, 36, 17
- score : 82, 73, 73, 90, 63
- name : 김, 이, 박, 최, 정

정렬 후
- age : 17, 24, 27, 24, 36
- score : 63, 73, 73, 82, 90
- name : 정, 박, 이, 김, 최

헤더파일 추가

벡터는 vector 헤더파일에 있다.

네임스페이스는 std를 이용한다.

#include <vector>

using namespace std;

구조체 선언

이름을 s로 갖는 구조체를 선언한다.

typedef struct {
	int age;
	int score;
	string name;
}s;

벡터 선언

구조체를 자료형으로 갖는 벡터를 선언한다.

vector<s>v;

비교함수 구현

정렬은 STL의 sort를 이용한다. sort는 algorithm 헤더파일에 있다.

sort의 인자로 필요한 비교함수를 구현한다.

bool compare(s a, s b) {
	if (a.score == b.score) {
		return a.age < b.age;
	}
	else {
		return a.score < b.score;
	}
}

socre를 기준으로 1차로 오름차순 정렬하고 만약 score의 두 값이 같다면 age를 기준으로 2차 오름차순 정렬한다.

compare 함수의 동작 원리는 위의 pair 벡터 정렬을 참고한다.

내림차순으로 정렬하려면 리턴값의 부등호를 반대로 바꾼다.

정렬 실행

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

전체 코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

typedef struct {
	int age;
	int score;
	string name;
}s;

bool compare(s a, s b) {
	if (a.score == b.score) {
		return a.age < b.age;
	}
	else {
		return a.score < b.score;
	}
}

void init(vector<s> &v){
	v.push_back({24, 82, "김"});
	v.push_back({27, 73, "이"});
	v.push_back({24, 73, "박"});
	v.push_back({36, 90, "최"});
	v.push_back({17, 63, "정"});
}

int main(){
	vector<s>v;
	init(v);
	sort(v.begin(), v.end(), compare);
}

Leave a Comment