728x90

 

정의
  • 구조체라 불리는 struct는 C++에서 제공 xxxx
  • 개발자의 커스텀한 자료구조
  • 커스텀하게 정렬을 추가하고 싶거나 문제에서 여러개의 변수가 들어간 자료구조가 필요하다면 struct를 사용 
  • 즉, 다른 유형의 항목들을 단일 유형으로 그룹화

예를 들어 int 타입의 2개의 멤버변수, double 타입의 3개의 멤버 변수가 필요하다고 하자.

  • 멤버변수
    • 클래스 또는 구조체 내부의 변수이자 메소드 밖에 있는 변수를 뜻한다.

 

구조체 정의
  • 아래 코드를 보면 Ralo라는 int 타입 2개의 멤버변수, double 타입 3개의 멤버 변수를 가진 간단한 구조체를 형성
  • 정해지지 않고 커스텀하게 만든 것을 볼 수 있으며
  • vector에도 집어넣을 수 있다.
  • 또한 만약 값을 집어넣지 않은 경우 0으로 초기화되는 것을 볼 수 있음
  • char 또는 string으로 선언한 경우 값을 안 넣는다면 빈 문자열
#include <bits/stdc++.h>
using namespace std;
struct Ralo{
    int a, b;
    double c, d, e;
};
void print(Ralo ralo){
    cout << ralo.a << " " << ralo.b << " " << ralo.c << " " << ralo.d << " " << ralo.e << '\n';
}
int main() {
    Ralo ralo = {1, 1, 1, 1, 1};
    print(ralo);
    vector<Ralo> ret;
    ret.push_back({1, 2, 3, 4, 5});
    ret.push_back({1, 2, 3, 4, 6});
	ret.push_back({});
    ret.push_back({1, 3});
    for(Ralo ralo : ret){
        print(ralo);
    }
    return 0;
}
/*
1 1 1 1 1
1 2 3 4 5
1 2 3 4 6
0 0 0 0 0
1 3 0 0 0
*/

 

  • 간단나 구조체를 집어넣은 vector를 정렬하기 위해서, 또는 a를 1순위로, b를 2순위로 정렬하고 싶다면 어떻게 해야될 까?
  • 이렇게 요구사항이 많아지게 되면 조금은 복잡하게 구조체를 구축해야 한다.

 

Point 구조체 정의
  • 아래 코드는 Point라는 구조체를 정의
  • 구조체를 기반으로 정렬하는 연산이 필요하다면 다음과 같은 형태로 구조체를 정의
struct Point{
    int y, x;             --- 1
    Point(int y, int x) : y(y), x(x){}      ----2
    Point(){ y = -1; x = -1; }   ---- 3
    bool operator < (const Point & a) const{    ----- 4
        if(x == a.x) return y < a.y;    ----- 5
        return x < a.x;
    }
};

 

  • 구조체의 멤버 변수 y, x를 정의 ---------------- 1
  • y, x를 받아 멤버변수를 생성한다는 의미 ----------------- 2
    • class의 constructor라는 매직메서드와 같다.
    • 즉, 이 구조체를 기반으로 객체를 생성 시 y, x를 받아 생성한다는 의미 
  • 만약 y, x가 정해지지 않은 경우 default value = -1, -1로 한다는 의미 ---------------- 3
  • 해당 구조체를 기반으로 만들어진 객체끼리 비교해야 되는 경우가 존재 -------------- 4, 5
    • 예를 들어 PointA < PointB와 같은 경우 비교하는 "기준"을 잡아준다.
    • 1순위는 x, 2순위는 y를 기반으로 크고 작음을 판단하는 코드 
    • 연산자(operator) 오버로딩   
    • 말 그대로 연산자를 오버로딩(하위 클래스에서 재정의) 하는 것 
    • 연산자는 <, > 등이 있음.              
    • 이 비교는 단순하게 if문으로도 비교할 때도 정의해야하지만 정렬할 때도 정의해주어야 한다.
    • 정렬이란 요소들을 비교해가며 정렬하는 것
    • 위의 코드를 기반으로 하면 x가 1순위, y가 2순위 "오름차순"으로 정렬
  • 만약 {1, 2}, {2, 3}이 만난다면 x는 서로 같이 않기 때문에 바로 밑의 return문으로 내려가게 되고 ----------------------- 5
    • x를 비교해서 {1, 2}가 더 작기 때문에 {1,2}와 {2,3}을 비교했을 때 {1,2}가 더 작다는 결론을 내린다.
    • 단순하게int 타입 변수 2개 int a = 1, int b = 2의 크기 비교하는 것처럼 구조체끼리도 크고 작음을 비교할 때는 이렇게 어떠한 멤버변수를 기준으로 할 것인지 등을 정해주어야 함

 

 

3개의 멤버변수 정렬
  • y, x, z가 필요하다고 생각
  • x를 1순위로 오름차순 정렬, y가 2순위로 내림차순, z가 3순위로 오름차순한다고 해보자.
  • 또한 초기값은 -1이 아니라 다른 수를 집어넣어도 된다.
struct Point{
    int y, x, z;
    Point(int y, int x, int z) : y(y), x(x), z(z){}
    Point(){y = -1; x = -1; z = -1; }
    bool operator < (const Point & a) const{
        if(x == a.x) {
            if(y == a.y) return z < a.z;
            return y > a.y;
        }
        return x < a.x;
    }
};

 

 

연산자 오버로딩을 넣지 않고 정렬
  • 위에서는 구조체 자체내에 bool operator ... 하고 커스텀 정렬을 구현했지만 따로 떼어서 하는 방법도 있음
#include <bits/stdc++.h>
using namespace std;
struct Point{
    int y, x;
};
bool cmp(const Point & a, const Point & b){
    return a.x > b.x;
}
vector<Point> v;
int main(){
    for(int i = 10; i >= 1; i--){
        v.push_back({i, 10 - i});
    }
    sort(v.begin(), v.end(), cmp);
    for(auto it : v) cout << it.y << " : " << it.x << "\n";
        return 0;
}

/*
1 : 9
2 : 8
3 : 7
4 : 6
5 : 5
6 : 4
7 : 3
8 : 2
9 : 1
10 : 0
*/

 

※ 참고 

  • 커스텀한 자료구조 만들 때 보통 class와 struct 사용
  • 코딩테스트에서는 -> struct만 알아도 충분
  • struct의 멤버변수
    • public, 상속 xxxxxxxx
  • class의 멤버변수
    • private, 상속 oooooo

 

728x90

'Programming Language > C++' 카테고리의 다른 글

[C++] ostream과 istream  (1) 2023.12.20
[C++] 입출력 기초  (1) 2023.12.20
[C++] queue, deque with Cpp  (1) 2023.12.20
[C++] Stack with Cpp  (0) 2023.12.20
[C++] set, multiset with Cpp  (0) 2023.12.20