챕터4. 실습문제

2025. 3. 27. 23:47Programming Languages/C++

4.5 실습 문제

문제 1: 재귀를 사용한 최대공약수(GCD) 계산

유클리드 알고리즘을 사용하여 두 정수의 최대공약수를 구하는 재귀 함수를 작성하세요.

#include <iostream>

// 재귀적 유클리드 알고리즘
int gcd(int a, int b) {
    if (b == 0) {
        return a;
    }
    return gcd(b, a % b);
}

int main() {
    int num1, num2;
    
    std::cout << "두 정수를 입력하세요: ";
    std::cin >> num1 >> num2;
    
    std::cout << num1 << "과 " << num2 << "의 최대공약수: " << gcd(num1, num2) << std::endl;
    
    return 0;
}

문제 2: 함수 템플릿을 사용한 배열 연산

배열의 합, 평균, 최댓값, 최솟값을 계산하는 다양한 함수 템플릿을 구현하세요.

#include <iostream>
#include <vector>

// 배열 합계 계산 템플릿
template<typename T>
T arraySum(const std::vector<T>& arr) {
    T sum = T();  // 기본값으로 초기화
    for (const T& value : arr) {
        sum += value;
    }
    return sum;
}

// 배열 평균 계산 템플릿
template<typename T>
double arrayAverage(const std::vector<T>& arr) {
    if (arr.empty()) {
        return 0.0;
    }
    return static_cast<double>(arraySum(arr)) / arr.size();
}

// 배열 최댓값 계산 템플릿
template<typename T>
T arrayMax(const std::vector<T>& arr) {
    if (arr.empty()) {
        throw std::invalid_argument("빈 배열에서 최댓값을 찾을 수 없습니다.");
    }
    
    T max = arr[0];
    for (const T& value : arr) {
        if (value > max) {
            max = value;
        }
    }
    return max;
}

// 배열 최솟값 계산 템플릿
template<typename T>
T arrayMin(const std::vector<T>& arr) {
    if (arr.empty()) {
        throw std::invalid_argument("빈 배열에서 최솟값을 찾을 수 없습니다.");
    }
    
    T min = arr[0];
    for (const T& value : arr) {
        if (value < min) {
            min = value;
        }
    }
    return min;
}

int main() {
    // 정수 배열 테스트
    std::vector<int> integers = {5, 2, 9, 1, 7, 6};
    
    std::cout << "정수 배열:" << std::endl;
    std::cout << "합계: " << arraySum(integers) << std::endl;
    std::cout << "평균: " << arrayAverage(integers) << std::endl;
    std::cout << "최댓값: " << arrayMax(integers) << std::endl;
    std::cout << "최솟값: " << arrayMin(integers) << std::endl;
    
    // 실수 배열 테스트
    std::vector<double> doubles = {3.14, 1.41, 2.71, 1.62, 2.0};
    
    std::cout << "\n실수 배열:" << std::endl;
    std::cout << "합계: " << arraySum(doubles) << std::endl;
    std::cout << "평균: " << arrayAverage(doubles) << std::endl;
    std::cout << "최댓값: " << arrayMax(doubles) << std::endl;
    std::cout << "최솟값: " << arrayMin(doubles) << std::endl;
    
    return 0;
}

문제 3: 콜백 함수를 사용한 이벤트 처리 시스템

사용자 정의 이벤트 처리 시스템을 구현하세요. std::function을 사용하여 다양한 이벤트 핸들러를 등록하고 호출할 수 있어야 합니다.

#include <iostream>
#include <string>
#include <functional>
#include <vector>
#include <map>

// 이벤트 종류
enum class EventType {
    ButtonClick,
    MouseMove,
    KeyPress,
    WindowResize
};

// 이벤트 데이터 기본 클래스
class EventData {
public:
    virtual ~EventData() = default;
};

// 버튼 클릭 이벤트 데이터
class ButtonClickData : public EventData {
public:
    std::string buttonName;
    int x, y;
    
    ButtonClickData(const std::string& name, int posX, int posY) 
        : buttonName(name), x(posX), y(posY) {}
};

// 키 입력 이벤트 데이터
class KeyPressData : public EventData {
public:
    char key;
    bool isShiftPressed;
    
    KeyPressData(char k, bool shift) : key(k), isShiftPressed(shift) {}
};

// 이벤트 처리 시스템
class EventSystem {
private:
    std::map<EventType, std::vector<std::function<void(const EventData&)>>> eventHandlers;
    
public:
    // 이벤트 핸들러 등록
    void addHandler(EventType type, std::function<void(const EventData&)> handler) {
        eventHandlers[type].push_back(handler);
    }
    
    // 이벤트 발생 시 관련 핸들러 호출
    void triggerEvent(EventType type, const EventData& data) {
        if (eventHandlers.find(type) != eventHandlers.end()) {
            for (const auto& handler : eventHandlers[type]) {
                handler(data);
            }
        }
    }
};

int main() {
    EventSystem eventSystem;
    
    // 버튼 클릭 핸들러 등록 (람다 함수)
    eventSystem.addHandler(EventType::ButtonClick, [](const EventData& data) {
        const auto& clickData = dynamic_cast<const ButtonClickData&>(data);
        std::cout << "버튼 클릭 이벤트: " << clickData.buttonName 
                  << " 위치: (" << clickData.x << ", " << clickData.y << ")" << std::endl;
    });
    
    // 키 입력 핸들러 등록 (일반 함수)
    auto keyHandler = [](const EventData& data) {
        const auto& keyData = dynamic_cast<const KeyPressData&>(data);
        std::cout << "키 입력 이벤트: " << keyData.key
                  << (keyData.isShiftPressed ? " (Shift 눌림)" : "") << std::endl;
    };
    eventSystem.addHandler(EventType::KeyPress, keyHandler);
    
    // 여러 이벤트 발생
    ButtonClickData clickData("확인 버튼", 150, 200);
    eventSystem.triggerEvent(EventType::ButtonClick, clickData);
    
    KeyPressData keyData('A', true);
    eventSystem.triggerEvent(EventType::KeyPress, keyData);
    
    return 0;
}

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

캡슐화와 접근 지정자  (0) 2025.03.28
객체 지향 프로그래밍  (0) 2025.03.27
함수 고급 주제  (0) 2025.03.27
재귀(Recursion)  (0) 2025.03.27
함수 포인터와 함수 객체  (0) 2025.03.27