Introduction to Practice Problems

Welcome to the practical segment of our C++ programming journey! Today, we're applying the knowledge from past lessons to solve two practice problems using advanced C++ Standard Template Library (STL) structures: std::queue and std::map with custom comparison operators through class definitions.

First Practice Problem: Implementing Queues with `std::queue`

Consider an event-driven system, like a restaurant. Orders arrive, and they must be handled in the order they were received, following the First In, First Out (FIFO) principle. This principle makes it a perfect scenario for a queue implementation in C++.

#include <iostream>
#include <queue>

class Queue {
private:
    std::queue<int> buffer;
public:
    void enqueue(int val) {
        // Adding (enqueueing) an item to the queue
        buffer.push(val);
    }

    int dequeue() {
        // Removing (dequeuing) an item from the queue
        if (!buffer.empty()) {
            int front = buffer.front();
            buffer.pop();
            return front;
        }
        throw std::out_of_range("Queue is empty");
    }

    // Checking if the queue is empty
    bool is_empty() const {
        return buffer.empty();
    }

    // Checking the size (number of items) in the queue
    size_t size() const {
        return buffer.size();
    }
};

int main() {
    Queue q;
    q.enqueue(1);
    q.enqueue(2);
    q.enqueue(3);
    
    std::cout << "Dequeued: " << q.dequeue() << '\n';
    std::cout << "Queue Size: " << q.size() << '\n';

    return 0;
}

This code demonstrates the creation and operation of a Queue class, which leverages std::queue to efficiently implement a queue. The Queue class includes methods to enqueue (add) an item, dequeue (remove) an item, check if the queue is empty, and return the queue's size. Enqueue operations add an item to the back of the queue, while dequeue operations remove an item from the front, maintaining the First In, First Out (FIFO) principle.

Second Practice Problem: Using Sorted Maps with Custom Class as a Key

For the second problem, imagine a leaderboard for a video game. Players with their scores can be represented as objects of a custom class, then stored in a std::map for easy and efficient access.

#include <iostream>
#include <map>
#include <string>

class Player {
public:
    std::string name;
    int score;
    
    Player(std::string n, int s) : name(n), score(s) {}

    // Custom comparison operator
    bool operator<(const Player& other) const {
        return score == other.score ? name < other.name : score < other.score;
    }
};

// Defining the output for Player object
std::ostream& operator<<(std::ostream& os, const Player& p) {
    os << "(" << p.name << ", " << p.score << ")";
    return os;
}

int main() {
    std::map<Player, int> scores;

    Player player1("John", 900);
    Player player2("Doe", 1000);

    // Adding players to the map
    scores[player1] = player1.score;
    scores[player2] = player2.score;

    // Print sorted map
    for (const auto& [player, score] : scores) {
        std::cout << player << '\n';
    }

    return 0;
}

This code snippet introduces a Player class representing players in a video game, with custom comparison operators to allow sorting by score (primary) and name (secondary). Instances of this class are then used as keys in a std::map, ensuring that players are stored in a manner sorted first by their scores and then by their names if scores are equal. This setup is crucial for functionalities like leaderboards, where players need to be ranked efficiently according to their performance.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal