코딩 학습/C와 C++

C++ 배치고사 선택 문제

이개 2026. 4. 3. 12:54

Map 활용: 데이터 자동 정렬, 가격 자동 갱신 

문제

상점에 등록될 아이템은 특정 규칙에 따라 자동으로 정렬되여야하며, 동일한 아이템이 들어올 경우 가격 갱신 로직이 실행되어야 합니다.

요구사항

  • 자료구조 정의: Item 구조체를 Key로, int(가격)를 Value로 하는 std::map을 사용하십시오.
  • 정렬 기준
    • 1순위: 공격력(attackPower) 내림차순 (높은 것이 앞)
    • 2순위: 공격력이 같다면 희귀도(rarity) 오름차순 (낮은 것이 앞)
    • 3순위: 위 두 조건이 모두 같다면 이름(name) 오름차순
  • 데이터 처리 (tryInsert 함수):
    • 필터링: 공격력이 50 미만인 아이템은 상점에 등록하지 않고 무시합니다.
    • 중복/갱신: 이미 상점에 있는 아이템(이름, 공격력, 희귀도가 모두 일치)이 다시 들어올 경우, 새로운 가격기존 가격보다 높을 때만 업데이트합니다. 
#include <iostream>
#include <string>
#include <map>
#include <vector>

using namespace std;

struct Item 
{
    string name;
    int attackPower;
    int rarity;

    // TODO: 요구사항에 맞는 비교 연산자 구현
    bool operator<(const Item& other) const 
    {
        if (this->attackPower != other.attackPower){
            return this->attackPower > other.attackPower;
        }

        if(this->rarity != other.rarity)
        {
            return this->rarity < other.rarity;
        }

        return this->name < other.name;
    }
};

// TODO: 조건부 삽입 및 가격 갱신 함수 구현
void tryInsert(map<Item, int>& shop, const Item& item, int price) 
{
   if(item.attackPower <= 50){
        return;
   }

   auto it = shop.find(item);

   if(it != shop.end())
   {
     if(price > it->second)
        it->second = price;
    }
    else
    {
    shop[item] = price;
    }
}

 

여기까지 풀었는데 어디서 2점 까인 건지 모르겠다. 아무래도 이 문제가 아닐까?

 

구조체나 클래스 비교할 때는 연산자 오버로딩을 통해 크기비교를 할 수 있게 해준다.

 

여기서 <만 재정의해준 이유는 Map 자료구조에서는 <만 사용하기 때문이다.

map<Item, int> shop;  // 내부적으로 < 만 사용해서 정렬

map이 내부적으로 < 로만 비교하기 때문에 이 코드에선 < 하나로 충분하다.

 

 

 

 

소소한 의문점: 같은 함수를 덮어쓰는 것처럼 보이는데, 왜 연산자 오버라이딩이 아니고 오버로딩일까?

왜 “오버로딩”이냐?

같은 연산자 +를 여러 타입에 대해 정의할 수 있음

 
int operator+(int a, int b); // 기본 제공
double operator+(double a, double b); // 기본 제공

// 우리가 추가
class Vec {
public:
int x, y;
Vec(int x, int y) : x(x), y(y) {}

Vec operator+(const Vec& other) {
return Vec(x + other.x, y + other.y);
}
};
 

👉 +가 여러 버전 존재
👉 타입에 따라 다른 함수 선택됨

✔ 이게 바로 오버로딩


오버라이딩이 아닌 이유

오버라이딩 조건:

  • 상속 관계 필요
  • virtual 함수 필요
  • 부모 함수 재정의

근데 연산자 오버로딩은:

 
Vec operator+(const Vec& other);
 

👉 그냥 새 함수 추가하는 거지
👉 부모 함수 덮어쓰는 게 아님

 

 

Vector 만들어보기 (3점)

#include <iostream>
#include <string>

template <typename T>
class MyVector 
{
private:
    T* Data;      // 동적 배열 포인터
    int Size;     // 현재 데이터 개수
    int Capacity; // 현재 최대 수용량

public:
    // [문제 1] 생성자 (3점)
    // 초기 용량(InCapacity)만큼 메모리를 할당하고 변수들을 초기화하세요.
    MyVector(int InCapacity = 2) 
    {
        // 로직 작성
    }

    ~MyVector() 
    {
        if (Data) delete[] Data;
    }

    // [문제 2] Add 함수 (12점)
    // 1. 만약 배열이 가득 찼다면(Size == Capacity), 용량을 2배로 늘려야 합니다.
    // 2. 새로운 메모리를 할당하고 기존 데이터를 안전하게 이사시킨 뒤, 이전 메모리를 해제하세요.
    // 3. 마지막에 새로운 데이터를 추가하세요.
    void Add(const T& InData) 
    {
        // 로직 작성 (메모리 재할당 프로세스 포함)
    }

    // [문제 3] operator[] 오버로딩 (5점)
    // 인덱스를 통해 데이터를 참조형으로 반환하세요.
    T& operator[](int Index) 
    {
        // 로직 작성
    }

    int GetSize() const { return Size; }
    int GetCapacity() const { return Capacity; }
};

int main() 
{
    // 테스트: 초기 용량은 2지만, 3개를 넣어서 재할당이 일어나는지 확인합니다.
    MyVector<int> Vec;
    Vec.Add(10);
    Vec.Add(20);
    
    std::cout << "Before Resize - Size: " << Vec.GetSize() << ", Capacity: " << Vec.GetCapacity() << std::endl;

    Vec.Add(30); // 여기서 재할당 로직이 실행되어야 함

    std::cout << "After Resize - Size: " << Vec.GetSize() << ", Capacity: " << Vec.GetCapacity() << std::endl;
    std::cout << "Data: " << Vec[0] << ", " << Vec[1] << ", " << Vec[2] << std::endl;

    return 0;
}
#include <iostream>
#include <string>

template <typename T>
class MyVector
{
private:
    T* Data;
    int Size;
    int Capacity;

public:
    // [문제 1] 생성자
    MyVector(int InCapacity = 2)
    {
        Capacity = InCapacity;
        Size = 0;
        Data = new T[Capacity];
    }

    ~MyVector()
    {
        if (Data) delete[] Data;
    }

    // [문제 2] Add 함수
    void Add(const T& InData)
    {
        if (Size == Capacity)
        {
            Capacity *= 2;
            T* NewData = new T[Capacity];

            for (int i = 0; i < Size; i++)
            {
                NewData[i] = Data[i];
            }

            delete[] Data;
            Data = NewData;
        }

        Data[Size] = InData;
        Size++;
    }

    // [문제 3] operator[] 오버로딩
    T& operator[](int Index)
    {
        return Data[Index];
    }

    int GetSize() const { return Size; }
    int GetCapacity() const { return Capacity; }
};