0% found this document useful (0 votes)
11 views38 pages

CC Lab 2 Report

Compiler Construction
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views38 pages

CC Lab 2 Report

Compiler Construction
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

Lab 2

Report

Submitted By :
Mehak Aftab
2021-CS-92

15 September 2024

UNIVERSITY OF ENGINEERING AND TECHNOLOGY

COMPUTER SCIENCE DEPARTMENT


Contents
1 Memory Management 5

2 Object-Oriented Programming 5
2.1 Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4 Virtual Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3 STL (Standard Template Library) Containers 7


3.1 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.3 Deque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.4 Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.5 Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.6 Priority Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.7 Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.8 Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.9 Unordered Map/Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

4 Templates 10
4.1 Function Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
4.2 Class Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
4.3 Template Specialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5 Algorithms 12
5.1 Sorting Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.1.1 std::sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.1.2 std::stables or t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.2 Searching Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5.2.1 std::binarys ear ch . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
5.2.2 std::find . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

6 Concurrency 14
6.1 Multithreading with std::thread . . . . . . . . . . . . . . . . . . . . . . . . . 14
6.2 Mutexes and Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

7 Problems 15
7.1 Task 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.2 Task 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
7.3 Task 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7.4 Task 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
7.5 Task 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2
7.6 Task 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.7 Task 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.8 Task 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
7.9 Task 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
7.10 Task 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
7.11 Task 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
7.12 Task 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

3
List of Figures
1 Task 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2 Task 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3 Task 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4 Task 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5 Task 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
6 Task 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
7 Task 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
8 Task 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
9 Task 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
10 Task 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
11 Task 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
12 Task 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

4
1 Memory Management
C++ allows to allocate memory dynamically in run-time. This is called Dynamic Memory
Allocation where we need to deallocate the dynamically allocated memory after we have no
use for a variable. For this purpose, we use “new” and “delete” operators to allocate and
deallocate memory respectively.
New Operator:
data_type* pointer_variable = new data_typevalue;
Delete Operator:
delete pointer_variable;

2 Object-Oriented Programming
2.1 Classes and Objects
A class is a blueprint for creating objects. It defines properties (attributes) and behaviors
(methods) which an object of the class can have.
An Object is an instance of a class. It holds the data and performs operations defined by its
class.
class Car {
public:
string model;
string color;

void drive() {
cout << "Driving the car." << endl;
}
};

int main() {
Car myCar; //Object of class Car
myCar.model = "Toyota";
myCar.color = "Red";
myCar.drive();
}

2.2 Struct
It is similar to a class but for simpler data structures. By default members of a struct are
public.
struct Book {
string title;

5
string author;
double price;
};

int main() {
Book myBook;
myBook.title = "Engineering a Compiler";
myBook.author = " Keith D. Cooper & Linda Torczon ";
myBook.price = 39.99;
}

2.3 Inheritance
This allows a new class (derived class) to inherit properties and behaviors from an existing
class (base class). It helps in re-using code and maintain hierarchical relationships between
classes.
class Animal {
public:
void eat() {
cout << "Eating" << endl;
}
};

class Dog : public Animal { //Dog is a derived class


public:
void bark() {
cout << "Barking" << endl;
}
};

int main() {
Dog myDog;
myDog.eat(); // Inherited from Animal
myDog.bark(); // Defined in Dog
}

2.4 Virtual Functions


These are functions in a base class that can be overridden in a derived class. This is called
Runtime Polymorphism where the decision of which function to call is made at runtime
according to the type of object pointed to by the base pointer.
class Animal {

6
public:
virtual void sound() { // Virtual function
cout << "Animal sound" << endl;
}
};

class Dog : public Animal {


public:
void sound() override { // Override the base class function
cout << "Bark" << endl;
}
};

int main() {
Animal* myAnimal = new Dog(); // Base class pointer pointing to derived class objec
myAnimal->sound(); // Outputs: Bark, because of runtime polymorphism
}

3 STL (Standard Template Library) Containers


3.1 Vectors
A vector is dynamic array which can resize itself automatically when an element is added or
removed. (Contiguous Memory Allocation)

Insert: O(1) or O(n) when re-sizing occurs


Find: O(1) when using an index otherwise O(n)
Delete: O(n) as shifting of elements occurs

Vectors are better when you need quick access by index or when you know there is frequent
re-sizing of an array.

3.2 Lists
It is doubly linked list, which means every element has pointers to both the previous and next
element. Doubly linked list use more memory space due to this than singly linked list as it
points to the next element only.

Insert: O(1) if inserting at the start or end otherwise O(n)


Find: O(n)
Delete: O(1) for deleting a known node otherwise O(n)

7
Lists are better than vectors when you need to make frequent insertions and deletions at
specific positions without shifting elements.

3.3 Deque
It allows insertion and deletion of elements from both ends. It can be implemented both as
a dynamic array or a doubly linked list.

Insert: O(1) at both ends


Find: O(n)
Delete: O(1) at both ends

Deque is better in scenarios when you need fast access at both ends, e.g. sliding window
scenario.

3.4 Stack
It is a last-In, First-Out data structure where elements are added and removed from top.

Insert: O(1) [Push operation]


Find: O(n)
Delete: O(1) [Pop operation]

Stack is better when you need to maintain a history of events.

3.5 Queue
It is a First-In, First-Out data structure where elements are added at the back and removed
from the front.

Insert: O(1) [Enqueue]


Find: O(n)
Delete: O(1) [Dequeue]

Queue is better when task scheduling is required.

8
3.6 Priority Queue
It is a special type of queue where each element is associated with a priority, and elements
are removed in order of their priority.

Insert: O(log n)
Find: O(1) to find the element with highest priority
Delete: O(log n) to remove the element with highest priority

It is better when we need to manage dynamic sets of elements with varying priorities.

3.7 Set
It is a collection of unique elements. [Implemented as a balanced binary search tree (like a
Red-Black Tree)]

Insert: O(log n)
Find: O(log n)
Delete: O(log n)

Set is better than unordered set when we need to maintain a sorted collection of unique
elements.

3.8 Map
It is a collection of key-value pairs, where each key is unique. [Implemented as a balanced
binary search tree (like a Red-Black Tree)]

Insert: O(log n)
Find: O(log n)
Delete: O(log n)

It is better when we need to maintain a sorted collection of key-value pairs and require ordered
traversal.

3.9 Unordered Map/Set


These are similar to maps and sets but are implemented using hash tables. It gives faster
access but elements are out of order.

9
Insert: O(1) on average while in case of collisions O(n)
Find: O(1) on average otherwise O(n)
Delete: O(1) on average otherwise O(n)

Unordered maps/sets are better than ordered maps/sets when order of elements does not
matter and you need fast access to elements.

4 Templates
4.1 Function Templates
They allow us to create generic functions that can operate on different data types without
rewriting the same function for each type. We define the function template once, and the
compiler generates the appropriate function according to the specific data type.
template <typename T>
T add(T a, T b) {
return a + b;
}

int main() {
int x = 5, y = 10;
double p = 5.5, q = 10.5;
cout << add(x, y) << endl; // Calls add<int>
cout << add(p, q) << endl; // Calls add<double>
return 0;
}

4.2 Class Templates


They allow us to create generic classes that can handle any data type. We define the class
template once, and the compiler generates the specific class implementation according to the
data type.
template <typename T>
class Pair {
private:
T first, second;
public:
Pair(T a, T b) : first(a), second(b) {}
T getFirst() const { return first; }
T getSecond() const { return second; }
};

10
int main() {
Pair<int> intPair(1, 2);
Pair<double> doublePair(3.4, 5.6);
cout << intPair.getFirst() << ", " << intPair.getSecond() << endl;
cout << doublePair.getFirst() << ", " << doublePair.getSecond() << endl;
return 0;
}

4.3 Template Specialization


It allows us to customize the behavior of a template for a specific type.
template <typename T>
class Printer {
public:
void print(T value) {
cout << "Generic print: " << value << endl;
}
};

// Template specialization for char*


template <>
class Printer<char*> {
public:
void print(char* value) {
cout << "Specialized print for char*: " << value << endl;
}
};

int main() {
Printer<int> intPrinter;
intPrinter.print(42); // Calls generic print

Printer<char*> charPrinter;
charPrinter.print("Hello"); // Calls specialized print
return 0;
}

11
5 Algorithms
5.1 Sorting Algorithms
5.1.1 std::sort
It is a non-stable sorting algorithm that sorts elements in ascending order by default using
the < operator.
Average case: O(N log N), Worst Case: O(N log N)
#include <algorithm>
#include <vector>
#include <iostream>

int main() {
std::vector<int> vec = {4, 2, 3, 1, 5};
std::sort(vec.begin(), vec.end());

for(int v : vec) {
std::cout << v << " "; // Output: 1 2 3 4 5
}
return 0;
}

5.1.2 std::stables or t
It is a stable sorting algorithm which means that it preserves the relative order of elements
with equal keys.
Average case: O(N log N), Worst Case: O(N log N)
#include <algorithm>
#include <vector>
#include <iostream>

struct Person {
std::string name;
int age;
};

bool compareByAge(const Person& a, const Person& b) {


return a.age < b.age;
}

int main() {
std::vector<Person> people = {{"Alice", 30}, {"Bob", 25}, {"Charlie", 25}};

12
std::stable_sort(people.begin(), people.end(), compareByAge);

for(const auto& p : people) {


std::cout << p.name << " " << p.age << std::endl;
// Output:
// Bob 25
// Charlie 25
// Alice 30
}
return 0;
}

5.2 Searching Algorithms


5.2.1 std::binarys ear ch
It checks if an element exists in a sorted range.
Complexity: O(log N)
#include <algorithm>
#include <vector>
#include <iostream>

int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
bool found = std::binary_search(vec.begin(), vec.end(), 3);
std::cout << (found ? "Found" : "Not Found") << std::endl; // Output: Found
return 0;
}

5.2.2 std::find
It searches for the first occurrence of a value in a range.
Complexity: 0(N)
#include <algorithm>
#include <vector>
#include <iostream>

int main() {
std::vector<int> vec = {4, 2, 3, 1, 5};
auto it = std::find(vec.begin(), vec.end(), 3);

if (it != vec.end()) {
std::cout << "Found: " << *it << std::endl; // Output: Found: 3

13
} else {
std::cout << "Not Found" << std::endl;
}
return 0;
}

6 Concurrency
6.1 Multithreading with std::thread
It is a class in the C++ Standard Library which represents a single thread of execution.
Threads are used to perform tasks concurrently.
#include <iostream>
#include <thread>

void printMessage(const std::string& message, int times) {


for (int i = 0; i < times; ++i) {
std::cout << message << std::endl;
}
}

int main() {
std::thread thread1(printMessage, "Hello from thread 1", 5);
std::thread thread2(printMessage, "Hello from thread 2", 5);

// Wait for threads to finish


thread1.join();
thread2.join();

std::cout << "Threads have finished execution." << std::endl;


return 0;
}

6.2 Mutexes and Locks


std::mutex is used to protect shared data from being accessed by multiple threads.
Std::lock_guard or std::unique_lock can be used to ensure that the mutex is automatically
released when lock is not in use anymore to prevent deadlocks.
#include <iostream>
#include <thread>
#include <mutex>

14
std::mutex mtx; // Mutex for critical section
int sharedCounter = 0;

void incrementCounter(int times) {


for (int i = 0; i < times; ++i) {
std::lock_guard<std::mutex> lock(mtx); // Locks mutex on entry and unlocks on e
++sharedCounter;
std::cout << "Thread " << std::this_thread::get_id() << " incremented counter t
}
}

int main() {
std::thread thread1(incrementCounter, 5);
std::thread thread2(incrementCounter, 5);

thread1.join();
thread2.join();

std::cout << "Final counter value: " << sharedCounter << std::endl;
return 0;
}

7 Problems
7.1 Task 1
#include <iostream>
#include <vector>

void displayGrades(const std::vector<int>& grades) {


std::cout << "Student Grades: ";
for (int grade : grades) {
std::cout << grade << " ";
}
std::cout << std::endl;
std::cout << "Current size: " << grades.size() << ", Capacity:
" << grades.capacity() << std::endl;
}

int main() {
std::vector<int> studentGrades;

std::cout << "Initial size: " << studentGrades.size() << ",

15
Capacity: " << studentGrades.capacity() << std::endl;

studentGrades.push_back(85);
studentGrades.push_back(90);
studentGrades.push_back(78);
studentGrades.push_back(92);

std::cout << "\nAfter adding 4 grades:" << std::endl;


displayGrades(studentGrades);

studentGrades.push_back(88);
studentGrades.push_back(76);
studentGrades.push_back(95);
studentGrades.push_back(83);

std::cout << "\nAfter adding 8 grades (showing dynamic


resizing):" << std::endl;
displayGrades(studentGrades);

int index = 3;
if (index < studentGrades.size()) {
std::cout << "\nGrade at index " << index << ": " <<
studentGrades[index] << std::endl;
}

index = 2;
if (index < studentGrades.size()) {
studentGrades.erase(studentGrades.begin() + index);
std::cout << "\nAfter deleting the grade at index " <<
index << ":" << std::endl;
displayGrades(studentGrades);
}

studentGrades.push_back(89);
studentGrades.push_back(91);

std::cout << "\nAfter adding 2 more grades:" << std::endl;


displayGrades(studentGrades);

return 0;
}

16
Figure 1: Task 1

7.2 Task 2
#include <iostream>
#include <string>

using namespace std;

class WebPage {
public:
string url;
WebPage* prev;
WebPage* next;

WebPage(string u) : url(u), prev(nullptr), next(nullptr) {}


};

class DoublyLinkedList {
private:
WebPage* head;
WebPage* tail;
WebPage* current;

public:
DoublyLinkedList() : head(nullptr), tail(nullptr), current(nullptr) {}

17
void addPage(string url) {
WebPage* newPage = new WebPage(url);

if (!head) {
head = tail = current = newPage;
} else {
newPage->prev = current;
if (current->next) {
WebPage* temp = current->next;
while (temp) {
WebPage* toDelete = temp;
temp = temp->next;
delete toDelete;
}
}
current->next = newPage;
tail = newPage;
current = newPage;
}
cout << "Visited: " << url << endl;
}

void moveForward() {
if (current && current->next) {
current = current->next;
cout << "Moved forward to: " << current->url << endl;
} else {
cout << "No more pages to move forward to." << endl;
}
}

void moveBackward() {
if (current && current->prev) {
current = current->prev;
cout << "Moved backward to: " << current->url << endl;
} else {
cout << "No more pages to move backward to." << endl;
}
}

void deleteCurrentPage() {
if (!current) {
cout << "No current page to delete." << endl;

18
return;
}

WebPage* toDelete = current;


if (current->prev)
current->prev->next = current->next;
if (current->next)
current->next->prev = current->prev;

if (current == head)
head = current->next;
if (current == tail)
tail = current->prev;

current = current->prev ? current->prev : current->next;

cout << "Deleted page: " << toDelete->url << endl;


delete toDelete;
}

void printCurrentPage() {
if (current) {
cout << "Current page: " << current->url << endl;
} else {
cout << "No current page." << endl;
}
}

~DoublyLinkedList() {
while (head) {
WebPage* temp = head;
head = head->next;
delete temp;
}
}
};

int main() {
DoublyLinkedList browserHistory;

browserHistory.addPage("http://example.com");
browserHistory.addPage("http://example.com/page1");
browserHistory.addPage("http://example.com/page2");

19
browserHistory.moveBackward();
browserHistory.printCurrentPage();

browserHistory.moveForward();
browserHistory.printCurrentPage();

browserHistory.deleteCurrentPage();
browserHistory.printCurrentPage();

return 0;
}

Figure 2: Task 2

7.3 Task 3
#include <iostream>
#include <deque>
#include <string>

using namespace std;

class TaskScheduler {
private:
deque<string> taskDeque;

20
public:
void addHighPriorityTask(const string& task) {
taskDeque.push_front(task);
cout << "Added high priority task at the front: " << task
<< endl;
}

void addRegularTask(const string& task) {


taskDeque.push_back(task);
cout << "Added regular task at the back: " << task << endl;
}

void removeFrontTask() {
if (!taskDeque.empty()) {
cout << "Removed task from the front: " <<
taskDeque.front() << endl;
taskDeque.pop_front();
} else {
cout << "No tasks to remove from the front." << endl;
}
}

void removeBackTask() {
if (!taskDeque.empty()) {
cout << "Removed task from the back: " <<
taskDeque.back() << endl;
taskDeque.pop_back();
} else {
cout << "No tasks to remove from the back." << endl;
}
}

void viewFrontTask() {
if (!taskDeque.empty()) {
cout << "Task at the front: " << taskDeque.front() <<
endl;
} else {
cout << "No tasks at the front." << endl;
}
}

void viewBackTask() {
if (!taskDeque.empty()) {

21
cout << "Task at the back: " << taskDeque.back() <<
endl;
} else {
cout << "No tasks at the back." << endl;
}
}

void displayAllTasks() {
if (taskDeque.empty()) {
cout << "No tasks in the queue." << endl;
return;
}

cout << "All tasks in the queue: " << endl;


for (const auto& task : taskDeque) {
cout << "- " << task << endl;
}
}
};

int main() {
TaskScheduler scheduler;

scheduler.addRegularTask("Task 1 - Regular");
scheduler.addHighPriorityTask("Task 2 - High Priority");
scheduler.addRegularTask("Task 3 - Regular");
scheduler.addHighPriorityTask("Task 4 - High Priority");

scheduler.displayAllTasks();

scheduler.viewFrontTask();
scheduler.viewBackTask();

scheduler.removeFrontTask();
scheduler.removeBackTask();

scheduler.displayAllTasks();

return 0;
}

22
Figure 3: Task 3

7.4 Task 4
#include <iostream>
#include <stack>
#include <string>

using namespace std;

bool areParenthesesBalanced(const string& expression) {


stack<char> s;
char current;

for (int i = 0; i < expression.length(); i++) {


current = expression[i];

if (current == '(' || current == '{' || current == '[') {


s.push(current);
}
else if (current == ')' || current == '}' || current ==
']') {
if (s.empty()) {
return false;
}

char top = s.top();

23
s.pop();

if ((current == ')' && top != '(') ||


(current == '}' && top != '{') ||
(current == ']' && top != '[')) {
return false;
}
}
}

return s.empty();
}

int main() {
string expression;

cout << "Enter a mathematical expression: ";


cin >> expression;

if (areParenthesesBalanced(expression)) {
cout << "The expression is balanced." << endl;
} else {
cout << "The expression is not balanced." << endl;
}

return 0;
}

Figure 4: Task 4

7.5 Task 5
#include <iostream>

24
#include <queue>
#include <string>

using namespace std;

struct Customer {
string name;
bool isVIP;

Customer(string name, bool isVIP) : name(name), isVIP(isVIP) {}


};

class CinemaTicketingSystem {
private:
queue<Customer> regularQueue;
queue<Customer> vipQueue;

public:
void addRegularCustomer(string name) {
regularQueue.push(Customer(name, false));
cout << name << " has joined the regular queue." << endl;
}

void addVIPCustomer(string name) {


vipQueue.push(Customer(name, true));
cout << name << " has joined the VIP queue." << endl;
}

void processNextCustomer() {
if (!vipQueue.empty()) {
Customer vipCustomer = vipQueue.front();
vipQueue.pop();
cout << "Serving VIP customer: " << vipCustomer.name <<
endl;
} else if (!regularQueue.empty()) {
Customer regularCustomer = regularQueue.front();
regularQueue.pop();
cout << "Serving regular customer: " << regularCustomer.name << endl;
} else {
cout << "No customers in the queue." << endl;
}
}

25
bool isEmpty() const {
return regularQueue.empty() && vipQueue.empty();
}
};

int main() {
CinemaTicketingSystem cinema;

cinema.addRegularCustomer("John");
cinema.addRegularCustomer("Alice");
cinema.addVIPCustomer("Mr. Smith");
cinema.addRegularCustomer("Bob");
cinema.addVIPCustomer("Ms. Taylor");

while (!cinema.isEmpty()) {
cinema.processNextCustomer();
}

return 0;
}

Figure 5: Task 5

7.6 Task 6
#include <iostream>
#include <queue>
#include <string>
#include <vector>

using namespace std;

26
struct Patient {
string name;
int severity;

Patient(string n, int s) : name(n), severity(s) {}


};

struct CompareSeverity {
bool operator()(const Patient& p1, const Patient& p2) {
return p1.severity < p2.severity;
}
};

class EmergencyRoomSystem {
private:
priority_queue<Patient, vector<Patient>, CompareSeverity> pq;

public:
void addPatient(string name, int severity) {
pq.push(Patient(name, severity));
cout << "Added patient: " << name << " with severity: " <<
severity << endl;
}

void treatNextPatient() {
if (pq.empty()) {
cout << "No patients in the queue." << endl;
} else {
Patient nextPatient = pq.top();
pq.pop();
cout << "Treating patient: " << nextPatient.name << "
with severity: " << nextPatient.severity << endl;
}
}

bool isEmpty() const {


return pq.empty();
}
};

int main() {
EmergencyRoomSystem emergencyRoom;

27
emergencyRoom.addPatient("John", 5);
emergencyRoom.addPatient("Alice", 8);
emergencyRoom.addPatient("Bob", 3);
emergencyRoom.addPatient("Eve", 10);
emergencyRoom.addPatient("Tom", 1);

while (!emergencyRoom.isEmpty()) {
emergencyRoom.treatNextPatient();
}

return 0;
}

Figure 6: Task 6

7.7 Task 7
#include <iostream>
#include <set>
#include <string>

using namespace std;

class CustomerEmails {
private:
set<string> emailSet;

public:

28
void insertEmail(const string& email) {
auto result = emailSet.insert(email);
if (result.second) {
cout << "Inserted email: " << email << endl;
} else {
cout << "Email already exists: " << email << endl;
}
}

void deleteEmail(const string& email) {


size_t removed = emailSet.erase(email);
if (removed > 0) {
cout << "Deleted email: " << email << endl;
} else {
cout << "Email not found: " << email << endl;
}
}

void searchEmail(const string& email) const {


if (emailSet.find(email) != emailSet.end()) {
cout << "Email found: " << email << endl;
} else {
cout << "Email not found: " << email << endl;
}
}

void displayEmails() const {


cout << "Unique email addresses:" << endl;
for (const auto& email : emailSet) {
cout << email << endl;
}
}
};

int main() {
CustomerEmails emailManager;

emailManager.insertEmail("[email protected]");
emailManager.insertEmail("[email protected]");
emailManager.insertEmail("[email protected]");

emailManager.displayEmails();

29
emailManager.searchEmail("[email protected]");
emailManager.searchEmail("[email protected]");

emailManager.deleteEmail("[email protected]");

emailManager.displayEmails();

return 0;
}

Figure 7: Task 7

7.8 Task 8
#include <iostream>
#include <map>
#include <string>

using namespace std;

struct StudentDetails {
string name;
float grade;

StudentDetails() {}
StudentDetails(string name, float grade) : name(name), grade(grade) {}
};

class StudentRecordManagement {

30
private:
map<int, StudentDetails> studentMap;

public:
void insertStudent(int id, const string& name, float grade) {
if (studentMap.find(id) != studentMap.end()) {
cout << "Student ID " << id << " already exists." <<
endl;
} else {
studentMap[id] = StudentDetails(name, grade);
cout << "Student ID " << id << " inserted successfully." << endl;
}
}

void deleteStudent(int id) {


if (studentMap.erase(id)) {
cout << "Student ID " << id << " deleted successfully." << endl;
} else {
cout << "Student ID " << id << " not found." << endl;
}
}

void retrieveStudent(int id) {


auto it = studentMap.find(id);
if (it != studentMap.end()) {
cout << "Student ID: " << it->first << endl;
cout << "Name: " << it->second.name << endl;
cout << "Grade: " << it->second.grade << endl;
} else {
cout << "Student ID " << id << " not found." << endl;
}
}

void displayAllStudents() {
if (studentMap.empty()) {
cout << "No student records available." << endl;
return;
}

cout << "Student Records:" << endl;


for (const auto& student : studentMap) {
cout << "Student ID: " << student.first << endl;
cout << "Name: " << student.second.name << endl;

31
cout << "Grade: " << student.second.grade << endl;
cout << "-------------------------" << endl;
}
}
};

int main() {
StudentRecordManagement manager;

manager.insertStudent(101, "John Doe", 85.5);


manager.insertStudent(102, "Jane Smith", 92.0);
manager.insertStudent(103, "David Johnson", 78.4);

manager.displayAllStudents();

manager.retrieveStudent(102);

manager.deleteStudent(101);

manager.retrieveStudent(101);

manager.displayAllStudents();

return 0;
}

Figure 8: Task 8

32
7.9 Task 9
#include <iostream>
#include <string>
#include <unordered_map>
#include <map>
#include <sstream>
#include <chrono>

using namespace std;


using namespace std::chrono;

void wordFrequencyUnorderedMap(const string &text) {


unordered_map<string, int> wordFreq;
stringstream ss(text);
string word;

auto start = high_resolution_clock::now();


while (ss >> word) {
wordFreq[word]++;
}
auto end = high_resolution_clock::now();

cout << "\nWord frequencies using unordered_map:\n";


for (const auto &entry : wordFreq) {
cout << entry.first << ": " << entry.second << endl;
}

auto duration = duration_cast<microseconds>(end - start).count();


cout << "Time taken using unordered_map: " << duration << "
microseconds\n";
}

void wordFrequencyMap(const string &text) {


map<string, int> wordFreq;
stringstream ss(text);
string word;

auto start = high_resolution_clock::now();


while (ss >> word) {
wordFreq[word]++;
}
auto end = high_resolution_clock::now();

33
cout << "\nWord frequencies using map:\n";
for (const auto &entry : wordFreq) {
cout << entry.first << ": " << entry.second << endl;
}

auto duration = duration_cast<microseconds>(end - start).count();


cout << "Time taken using map: " << duration << " microseconds\n";
}

int main() {
string text = "This is a sample text with several words this
is a test text with repeated words text repeated repeated";

wordFrequencyUnorderedMap(text);

wordFrequencyMap(text);

return 0;
}

Figure 9: Task 9

34
7.10 Task 10
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

struct Student {
std::string name;
int grade;
};

bool compareStudents(const Student &a, const Student &b) {


if (a.grade != b.grade) {
return a.grade > b.grade;
}
return a.name < b.name;
}

int main() {
std::vector<Student> students = {
{"John", 85},
{"Alice", 95},
{"Bob", 85},
{"Charlie", 70},
{"David", 95},
{"Eve", 85}
};

std::sort(students.begin(), students.end(), compareStudents);

for (const auto &student : students) {


std::cout << student.name << ": " << student.grade << std::endl;
}

return 0;
}

35
Figure 10: Task 10

7.11 Task 11
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

struct Employee {
std::string name;
std::string department;
std::string hireDate;
};

bool compareByDepartment(const Employee &a, const Employee &b) {


return a.department < b.department;
}

int main() {
std::vector<Employee> employees = {
{"John", "HR", "2022-05-01"},
{"Alice", "Engineering", "2021-01-15"},
{"Bob", "HR", "2020-11-20"},
{"Charlie", "Engineering", "2019-06-30"},
{"David", "Marketing", "2023-03-22"},
{"Eve", "Engineering", "2022-08-01"}
};

std::stable_sort(employees.begin(), employees.end(), compareByDepartment);

for (const auto &employee : employees) {


std::cout << employee.name << " | " << employee.department

36
<< " | " << employee.hireDate << std::endl;
}

return 0;
}

Figure 11: Task 11

7.12 Task 12
#include <iostream>
#include <thread>

void print1to5() {
for (int i = 1; i <= 5; ++i) {
std::cout << "Thread 1: " << i << std::endl;
}
}

void print6to10() {
for (int i = 6; i <= 10; ++i) {
std::cout << "Thread 2: " << i << std::endl;
}
}

int main() {
std::thread t1(print1to5);
std::thread t2(print6to10);

t1.join();
t2.join();

37
return 0;
}

Figure 12: Task 12

38

You might also like