39. Exercises – Modern C++ for Absolute Beginners: A Friendly Introduction to C++ Programming Language and C++11 to C++20 Standards

© Slobodan Dmitrović 2020
S. DmitrovićModern C++ for Absolute Beginnershttps://doi.org/10.1007/978-1-4842-6047-0_39

39. Exercises

Slobodan Dmitrović1 
(1)
Belgrade, Serbia
 

39.1 Basic Vector

Write a program that defines a vector of integers. Insert two elements into a vector. Print out the vector content using the range-based loop .
#include <iostream>
#include <vector>
int main()
{
    std::vector<int> v = { 10, 5, 8, 4, 1, 2 };
    v.push_back(15); // insert the value 15
    v.push_back(30); // insert the value of 30
    for (auto el : v)
    {
        std::cout << el << '\n';
    }
}

39.2 Deleting a Single Value

Write a program that defines a vector of integers. Erase the second element from the vector. Print out the vector content using the range-based loop .
#include <iostream>
#include <vector>
int main()
{
    std::vector<int> v = { 10, 5, 8, 4, 1, 2 };
    v.erase(v.begin() + 1); // erase the second element which is 5
    for (auto el : v)
    {
        std::cout << el << '\n';
    }
}

39.3 Deleting a Range of Elements

Write a program that defines a vector of integers. Erase the range of 3 elements starting from the beginning of the vector. Print out the vector content using the range-based loop.
#include <iostream>
#include <vector>
int main()
{
    std::vector<int> v = { 10, 5, 8, 4, 1, 2 };
    v.erase(v.begin(), v.begin() + 3); // erase the first 3 elements
    for (auto el : v)
    {
        std::cout << el << '\n';
    }
}

In this case the .erase() function overload accepts two arguments. One is the beginning of the range to be deleted. In our case, it is marked with v.begin(). The second argument is the end of the range to be deleted.In our case, it is the v.begin() + 3 iterator. Please note that instead of .begin() member function we could have used a freestanding std::begin(v) function.

39.4 Finding Elements in a Vector

Write a program that searches for a vector element using the std::find() algorithm function. If the element has been found, delete it. Print out the vector content.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
    std::vector<int> v = { 10, 5, 8, 4, 1, 2 };
    int findnumber = 4;
    auto foundit = std::find(std::begin(v), std::end(v), findnumber);
    if (foundit != std::end(v))
    {
        std::cout << "Element found. Deleting the element." << '\n';
        v.erase(foundit);
        std::cout << "Element deleted." << '\n';
    }
    else
    {
        std::cout << "Element not found." << '\n';
    }
    for (auto el : v)
    {
        std::cout << el << '\n';
    }
}

39.5 Basic Set

Write a program that defines a set of integers. Print out the set content and observe the following: the data is sorted, regardless of how we defined the set. This is because internally, std::set is a sorted container that holds unique values.
#include <iostream>
#include <set>
int main()
{
    std::set<int> myset = { -10, 1, 3, 5, -20, 6, 9, 15 };
    for (auto el : myset)
    {
        std::cout << el << '\n';
    }
}

39.6 Set Data Manipulation

Write a program that defines a set and inserts two new values using the set’s .insert() member function. Then, delete one arbitrary value from a set using the set’s .erase() member function. Print out the set content afterward.
#include <iostream>
#include <set>
int main()
{
    std::set<int> myset = { -10, 1, 3, 5, 6, 9, 15 };
    myset.insert(-5); // inserts a value of -5
    myset.insert(30); // inserts a value of 30
    myset.erase(6); // deletes a value of 6
    for (auto el : myset)
    {
        std::cout << el << '\n';
    }
}

39.7 Set Member Functions

Write a program that defines a set of integers and utilizes the set’s member function to check the set’s size, check whether it is empty and clear the set’s content.
#include <iostream>
#include <set>
int main()
{
    std::set<int> myset = { -10, 1, 3, 5, 6, 9, 15 };
    std::cout << "The set's size is: " << myset.size() << '\n';
    std::cout << "Clearing the set..." << '\n';
    myset.clear(); // clear the set's content
    if (myset.empty())
    {
        std::cout << "The set is empty." << '\n';
    }
    else
    {
        std::cout << "The set is not empty." << '\n';
    }
}

39.8 Search for Data in a Set

Write a program that searches for a particular value in a set using the set’s .find() member function. If the value is found, delete it. Print out the set content.
#include <iostream>
#include <set>
int main()
{
    std::set<int> myset = { -10, 1, 3, 5, 6, 9, 15 };
    int findvalue = 5;
    auto foundit = myset.find(findvalue);
    if (foundit != myset.end())
    {
        std::cout << "Value found. Deleting the value..." << '\n';
        myset.erase(foundit);
        std::cout << "Element deleted." << '\n';
    }
    else
    {
        std::cout << "Value not found." << '\n';
    }
    for (auto el : myset)
    {
        std::cout << el << '\n';
    }
}

39.9 Basic Map

Write a program that defines a map where keys are of type char and values are of type int. Print out the map content.
#include <iostream>
#include <map>
int main()
{
    std::map<char, int> mymap = { {'a', 1}, {'b', 5}, {'e', 10}, {'f', 10} };
    for (auto el : mymap)
    {
        std::cout << el.first << ' ' << el.second << '\n';
    }
}

Explanation. Map elements are key-value pairs. These pairs are represented by an std::pair class template which can store a pair. So the type of a map element is std::pair<char, int>.In a map container, keys are unique, and values do not have to be unique. We initialize the map with our key-value pairs inside the initializer list {}. Using a ranged-based for loop, we iterate over map elements. To access the key in a pair, we use the pair’s .first member function, which represents the first element in a pair, in our case – the key. Similarly, we access the second element using the pair’s .second member function, which represents the map element value.

39.10 Inserting Into Map

Write a program that defines a map of strings and integers. Insert an element into a map using the map’s .insert() member function. Then use the map’s operator [] to insert another key-value element into a map. Print the map content afterward.
#include <iostream>
#include <map>
#include <string>
int main()
{
    std::map<std::string, int> mymap = { {"red", 1}, {"green", 20}, {"blue", 15} };
    mymap.insert({ "magenta", 4 });
    mymap["yellow"] = 5;
    for (const auto& el : mymap)
    {
        std::cout << el.first << ' ' << el.second << '\n';
    }
}

When using the map’s [] operator, there are two scenarios. The key inside the [] operator exists in the map. This means we can use it to change the value of an element. The key does not exist. In this case, when using the map’s operator [], the key-value gets inserted into the map. This was the case with our: mymap["yellow"] = 5; statement. Remember, maps are graphs, and the map’s elements are sorted based on a key. And since our keys are strings, the order does not necessarily need to be the one we provided in the initializer list.

If, for example, we have a map of ints and strings, and we provide sorted int keys in the initializers list, the order would be the same when printing out the elements:
#include <iostream>
#include <map>
#include <string>
int main()
{
    std::map<int, std::string> mymap = { {1, "First"}, {2, "Second"}, {3, "Third"}, {4, "Fourth"} };
    for (const auto& el : mymap)
    {
        std::cout << el.first << ' ' << el.second << '\n';
    }
}

39.11 Searching and Deleting From a Map

Write a program that defines a map of integers and strings. Search for an element by key using the map’s .find() member function. If the element is found, delete it. Print out the map content.
#include <iostream>
#include <map>
#include <string>
int main()
{
    std::map<int, std::string> mymap = { {1, "First"}, {2, "Second"}, {3, "Third"}, {4, "Fourth"} };
    int findbykey = 2;
    auto foundit = mymap.find(findbykey);
    if (foundit != mymap.end())
    {
        std::cout << "Key found." << '\n';
        std::cout << "Deleting the element..." << '\n';
        mymap.erase(foundit);
    }
    else
    {
        std::cout << "Key not found." << '\n';
    }
    for (const auto& el : mymap)
    {
        std::cout << el.first << ' ' << el.second << '\n';
    }
}

39.12 Lambda Expressions

Write a program that defines a vector of integers. Sort the vector in a descending order using the std::sort function, and a user-provided lambda function as a predicate.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
    std::vector<int> v = { 5, 10, 4, 1, 3, 15 };
    std::sort(std::begin(v), std::end(v), [](int x, int y) {return x > y; });
    for (const auto& el : v)
    {
        std::cout << el << '\n';
    }
}
Write a program that defines a vector of integers. Use the std::count_if function and a user-provided lambda function to count only even numbers.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
    std::vector<int> v = { 5, 10, 4, 1, 3, 8 };
    int mycount = std::count_if(std::begin(v), std::end(v), [](int x) {return x % 2 == 0; });
    std::cout << "The number of even numbers is: " << mycount;
}
Write a program that defines a local lambda expression that can capture and modify the variable defined inside the main() function:
#include <iostream>
int main()
{
    int x = 123;
    std::cout << "The value of a local variable is: " << x << '\n';
    auto mylambda = [&x](){ x++; };
    mylambda();
    std::cout << "Lambda captured and changed the local variable to: " << x << '\n';
}