Examples of problems and solutions in C++

⏱️ Estimated Reading Time: ~16 min read
0
(0)

Problem 1.

Singly linked list. Implement a list of strings. Write functions to count the number of words in the list:
a. beginning and ending with the same letter
b. beginning with the same letter as the next word
c. matching the last word.

Solution:

Here is a C++ implementation of a singly linked list storing strings, along with the three counting functions.

C++

#include <iostream>
#include <string>
#include <cctype>

struct Node {
    std::string word;
    Node* next;

    Node(const std::string& val) : word(val), next(nullptr) {}
};

class StringLinkedList {
private:
    Node* head;

public:
    StringLinkedList() : head(nullptr) {}

    ~StringLinkedList() {
        Node* current = head;
        while (current != nullptr) {
            Node* temp = current;
            current = current->next;
            delete temp;
        }
    }

    void append(const std::string& word) {
        Node* newNode = new Node(word);
        if (head == nullptr) {
            head = newNode;
            return;
        }
        Node* current = head;
        while (current->next != nullptr) {
            current = current->next;
        }
        current->next = newNode;
    }

    // Helper: Normalize character for case-insensitive comparison
    char toLowerChar(char ch) const {
        return std::tolower(static_cast<unsigned char>(ch));
    }

    // a. Count words beginning and ending with the same letter
    int countSameStartAndEnd() const {
        int count = 0;
        Node* current = head;

        while (current != nullptr) {
            const std::string& word = current->word;
            if (!word.empty()) {
                char firstChar = toLowerChar(word.front());
                char lastChar = toLowerChar(word.back());
                if (firstChar == lastChar) {
                    count++;
                }
            }
            current = current->next;
        }
        return count;
    }

    // b. Count words beginning with the same letter as the next word
    int countSameStartAsNext() const {
        int count = 0;
        Node* current = head;

        while (current != nullptr && current->next != nullptr) {
            const std::string& currWord = current->word;
            const std::string& nextWord = current->next->word;

            if (!currWord.empty() && !nextWord.empty()) {
                char currFirst = toLowerChar(currWord.front());
                char nextFirst = toLowerChar(nextWord.front());
                if (currFirst == nextFirst) {
                    count++;
                }
            }
            current = current->next;
        }
        return count;
    }

    // c. Count words matching the last word in the list
    int countMatchingLastWord() const {
        if (head == nullptr) return 0;

        // Find the last node
        Node* current = head;
        while (current->next != nullptr) {
            current = current->next;
        }
        std::string lastWord = current->word;

        // Count occurrences matching the last word
        int count = 0;
        current = head;
        while (current != nullptr) {
            if (current->word == lastWord) {
                count++;
            }
            current = current->next;
        }
        return count;
    }
};

int main() {
    StringLinkedList list;

    // Example words: "radar", "apple", "anaconda", "banana", "boat", "apple"
    list.append("radar");
    list.append("apple");
    list.append("anaconda");
    list.append("banana");
    list.append("boat");
    list.append("apple");

    std::cout << "a. Beginning and ending with same letter: " 
              << list.countSameStartAndEnd() << " (e.g., radar, anaconda)\n";

    std::cout << "b. Beginning with same letter as next word: " 
              << list.countSameStartAsNext() << " (e.g., apple->anaconda, banana->boat)\n";

    std::cout << "c. Matching the last word (\"apple\"): " 
              << list.countMatchingLastWord() << " (first and last node)\n";

    return 0;
}

Explanation of the Functions

  • countSameStartAndEnd(): Iterates through each node, converts the first (word.front()) and last (word.back()) characters to lowercase, and increments the count if they match.

  • countSameStartAsNext(): Uses lookahead (current->next) to compare the initial character of current->word with the initial character of current->next->word. It stops at the second-to-last node.

  • countMatchingLastWord(): Operates in two passes over the list—the first pass traverses to the tail to fetch the target string, and the second pass counts how many nodes contain exact string matches to that target (including the last node itself).

 

The output produced by executing the C++ code above:

Plaintext

a. Beginning and ending with same letter: 2 (e.g., radar, anaconda)
b. Beginning with same letter as next word: 2 (e.g., apple->anaconda, banana->boat)
c. Matching the last word ("apple"): 2 (first and last node)

Breakdown of the Results

  • a. Same start & end letter:

    • "radar" (starts and ends with ‘r’)  → Match

    • "apple" (starts with ‘a’, ends with ‘e’)

    • "anaconda" (starts and ends with ‘a’)  → Match

    • Total = 2

  • b. Same start letter as the next word:

    • "apple" (‘a’) → "anaconda" (‘a’)  → Match

    • "banana" (‘b’)  →"boat" (‘b’) → Match

    • Total = 2

  • c. Matches the last word ("apple"):

    • Node 1 ("apple") and Node 6 ("apple")

    • Total = 2

 

Alternatively:

Below is a complete C++ implementation using a singly linked list of strings. It includes separate functions for all three requirements.

#include <iostream>
#include <string>
using namespace std;

// Node structure
struct Node {
    string word;
    Node* next;

    Node(string w) {
        word = w;
        next = nullptr;
    }
};

// Insert a word at the end of the list
void insertEnd(Node*& head, string word) {
    Node* newNode = new Node(word);

    if (head == nullptr) {
        head = newNode;
        return;
    }

    Node* temp = head;
    while (temp->next != nullptr) {
        temp = temp->next;
    }

    temp->next = newNode;
}

// Display the list
void display(Node* head) {
    Node* temp = head;

    while (temp != nullptr) {
        cout << temp->word << " -> ";
        temp = temp->next;
    }

    cout << "NULL" << endl;
}

// a. Count words beginning and ending with the same letter
int countSameFirstLast(Node* head) {
    int count = 0;
    Node* temp = head;

    while (temp != nullptr) {
        if (!temp->word.empty() &&
            temp->word.front() == temp->word.back()) {
            count++;
        }

        temp = temp->next;
    }

    return count;
}

// b. Count words beginning with the same letter as the next word
int countSameAsNext(Node* head) {
    int count = 0;
    Node* temp = head;

    while (temp != nullptr && temp->next != nullptr) {
        if (!temp->word.empty() &&
            !temp->next->word.empty() &&
            temp->word.front() == temp->next->word.front()) {
            count++;
        }

        temp = temp->next;
    }

    return count;
}

// c. Count words matching the last word
int countMatchingLastWord(Node* head) {
    if (head == nullptr)
        return 0;

    // Find the last word
    Node* last = head;

    while (last->next != nullptr) {
        last = last->next;
    }

    string lastWord = last->word;
    int count = 0;

    // Compare every word with the last word
    Node* temp = head;

    while (temp != nullptr) {
        if (temp->word == lastWord) {
            count++;
        }

        temp = temp->next;
    }

    return count;
}

// Main function
int main() {
    Node* head = nullptr;

    // Create the list
    insertEnd(head, "level");
    insertEnd(head, "apple");
    insertEnd(head, "ant");
    insertEnd(head, "area");
    insertEnd(head, "level");
    insertEnd(head, "banana");
    insertEnd(head, "level");

    cout << "Singly Linked List:" << endl;
    display(head);

    // a
    cout << "\na. Words beginning and ending with the same letter: "
         << countSameFirstLast(head) << endl;

    // b
    cout << "b. Words beginning with the same letter as the next word: "
         << countSameAsNext(head) << endl;

    // c
    cout << "c. Words matching the last word: "
         << countMatchingLastWord(head) << endl;

    return 0;
}

How the three functions work

a. Beginning and ending with the same letter

For each word, compare its first and last characters:

temp->word.front() == temp->word.back()

For example, level qualifies because it starts with l and ends with l.

b. Beginning with the same letter as the next word

Compare the first letter of the current node with the first letter of the next node:

temp->word.front() == temp->next->word.front()

For example:

apple -> ant
  a       a

So apple is counted.

The last node isn’t checked because it has no next word.

c. Matching the last word

First, traverse the list to find the last node:

while (last->next != nullptr) {
    last = last->next;
}

Then compare every word with that last word:

if (temp->word == lastWord)
    count++;

The output of the provided C++ program is:

Singly Linked List:
level -> apple -> ant -> area -> level -> banana -> level -> NULL

a. Words beginning and ending with the same letter: 4
b. Words beginning with the same letter as the next word: 2
c. Words matching the last word: 3

In the example, the last word is level, and level occurs 3 times, so the result for (c) is 3.

Problem 2.

Two-dimensional array. The characteristic of a column of an integer matrix is ​​the sum of the absolute values ​​of its negative odd elements. By permuting the columns of the given matrix, arrange them in increasing order of their characteristics.

 

Solution:

simple C++ solution for the two-dimensional array problem.

Idea

For every column:

  1. Look through all its elements.
  2. Select elements that are:
    • negative (x < 0)
    • odd (x % 2 != 0)
  3. Add their absolute values to get the column’s characteristic.
  4. Sort the columns in increasing order of these characteristics.

For example, if a column contains:

  2
 -3
 -5
  4

its characteristic is:

|-3| + |-5| = 3 + 5 = 8

C++ Program

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

const int MAX = 100;

// Structure to store a column and its characteristic
struct Column {
    int values[MAX];
    int characteristic;
};

// Calculate the characteristic of a column
int getCharacteristic(int column[], int rows) {
    int sum = 0;

    for (int i = 0; i < rows; i++) {
        // Negative and odd
        if (column[i] < 0 && column[i] % 2 != 0) {
            sum += abs(column[i]);
        }
    }

    return sum;
}

// Swap two columns
void swapColumns(int matrix[][MAX], int rows, int col1, int col2) {
    for (int i = 0; i < rows; i++) {
        swap(matrix[i][col1], matrix[i][col2]);
    }
}

int main() {
    int rows, cols;
    int matrix[MAX][MAX];

    cout << "Enter number of rows: ";
    cin >> rows;

    cout << "Enter number of columns: ";
    cin >> cols;

    cout << "Enter the matrix elements:\n";

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cin >> matrix[i][j];
        }
    }

    // Calculate characteristics
    int characteristic[MAX];

    for (int j = 0; j < cols; j++) {
        int sum = 0;

        for (int i = 0; i < rows; i++) {
            if (matrix[i][j] < 0 && matrix[i][j] % 2 != 0) {
                sum += abs(matrix[i][j]);
            }
        }

        characteristic[j] = sum;
    }

    // Sort columns according to their characteristics
    for (int i = 0; i < cols - 1; i++) {
        for (int j = 0; j < cols - i - 1; j++) {

            if (characteristic[j] > characteristic[j + 1]) {

                // Swap characteristics
                swap(characteristic[j], characteristic[j + 1]);

                // Swap the corresponding columns
                swapColumns(matrix, rows, j, j + 1);
            }
        }
    }

    // Display characteristics
    cout << "\nCharacteristics of columns in increasing order:\n";

    for (int j = 0; j < cols; j++) {
        cout << characteristic[j] << " ";
    }

    // Display sorted matrix
    cout << "\n\nMatrix after sorting columns:\n";

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << matrix[i][j] << "\t";
        }
        cout << endl;
    }

    return 0;
}

Example

Suppose the input matrix is:

  1   -3    4   -7
 -5    2   -9    6
  8   -1    3   -2

The characteristics are:

  • Column 1: |-5| = 5
  • Column 2: |-3| + |-1| = 4
  • Column 3: |-9| = 9
  • Column 4: |-7| = 7

Therefore:

4, 5, 7, 9

The columns are rearranged according to that order.

Important: when swapping the characteristic values, we must also swap the entire corresponding columns of the matrix. This is what swapColumns() does.

Using std::vector makes the program shorter because we don’t need fixed-size arrays or a separate function to swap columns.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

int main() {
    int rows, cols;

    cout << "Enter rows and columns: ";
    cin >> rows >> cols;

    vector<vector<int>> matrix(rows, vector<int>(cols));

    cout << "Enter matrix elements:\n";
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            cin >> matrix[i][j];

    // Store each column together with its characteristic
    vector<pair<int, vector<int>>> columns;

    for (int j = 0; j < cols; j++) {
        int characteristic = 0;
        vector<int> column;

        for (int i = 0; i < rows; i++) {
            column.push_back(matrix[i][j]);

            // Negative odd element
            if (matrix[i][j] < 0 && matrix[i][j] % 2 != 0)
                characteristic += abs(matrix[i][j]);
        }

        columns.push_back({characteristic, column});
    }

    // Sort columns by their characteristics
    sort(columns.begin(), columns.end());

    // Put sorted columns back into the matrix
    for (int j = 0; j < cols; j++)
        for (int i = 0; i < rows; i++)
            matrix[i][j] = columns[j].second[i];

    // Display the characteristics
    cout << "\nCharacteristics:\n";
    for (auto &col : columns)
        cout << col.first << " ";

    // Display the sorted matrix
    cout << "\n\nSorted matrix:\n";
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++)
            cout << matrix[i][j] << "\t";
        cout << endl;
    }

    return 0;
}

The important part

We store each column as:

pair<int, vector<int>>

where:

first  → characteristic
second → actual column

For example:

(5, {-5, 2, 8})
(4, {-3, 2, -1})
(9, {4, -9, 3})

Then:

sort(columns.begin(), columns.end());

automatically sorts them by the first value, which is the characteristic.

So the columns become ordered:

(4, {-3, 2, -1})
(5, {-5, 2, 8})
(9, {4, -9, 3})

This is considerably shorter and avoids manually implementing column swapping.

Problem 3.

Implement a calculator in C++ capable of performing four arithmetic operations. Prompt the user for arguments and the operation sign (symbol). Loop the program—after displaying the result, prompt the user to perform the calculation again. Exit the program by pressing the q key. Perform checks: 1) division by zero (in this case, display a warning message and prompt for the divisor again); 2) correct entry of the operation sign (in this case, prompt the user to enter the correct operation sign).

 

Solution:

A simple C++ calculator that performs addition, subtraction, multiplication, and division, with both required checks.

#include <iostream>
using namespace std;

int main() {
    double a, b, result;
    char operation;
    char again;

    do {
        cout << "\nEnter first number: ";
        cin >> a;

        // Get a valid operation sign
        while (true) {
            cout << "Enter operation (+, -, *, /): ";
            cin >> operation;

            if (operation == '+' || operation == '-' ||
                operation == '*' || operation == '/') {
                break;
            }

            cout << "Invalid operation! Please enter +, -, * or /.\n";
        }

        // Get the second number
        cout << "Enter second number: ";
        cin >> b;

        // Check division by zero
        while (operation == '/' && b == 0) {
            cout << "Warning: Division by zero is not allowed!\n";
            cout << "Enter the divisor again: ";
            cin >> b;
        }

        // Perform the calculation
        switch (operation) {
            case '+':
                result = a + b;
                break;

            case '-':
                result = a - b;
                break;

            case '*':
                result = a * b;
                break;

            case '/':
                result = a / b;
                break;
        }

        cout << "Result = " << result << endl;

        // Ask whether to continue
        cout << "\nPress any key to calculate again, or q to quit: ";
        cin >> again;

    } while (again != 'q' && again != 'Q');

    cout << "Calculator closed. Goodbye!\n";

    return 0;
}

Example

Enter first number: 20
Enter operation (+, -, *, /): /
Enter second number: 0
Warning: Division by zero is not allowed!
Enter the divisor again: 5
Result = 4

Press any key to calculate again, or q to quit: y

Enter first number: 10
Enter operation (+, -, *, /): *
Enter second number: 3
Result = 30

Press any key to calculate again, or q to quit: q
Calculator closed. Goodbye!

How the checks work

1. Division by zero

while (operation == '/' && b == 0) {
    cout << "Warning: Division by zero is not allowed!\n";
    cout << "Enter the divisor again: ";
    cin >> b;
}

The program keeps asking for the divisor until the user enters a non-zero value.

2. Invalid operation sign

while (true) {
    cin >> operation;

    if (operation == '+' || operation == '-' ||
        operation == '*' || operation == '/') {
        break;
    }

    cout << "Invalid operation!\n";
}

The program accepts only +, -, *, and /.

3. Exit with q

} while (again != 'q' && again != 'Q');

The calculator continues until the user enters q or Q.

Problem 4.

Working with strings. The input is an array of strings and its length. Each string has the form “Last Name First Name Middle Name” (separated by a single space). The function should return a new array consisting of strings of the form “First Name Last Name”.

 

Solution:

This problem asks us to write a C++ function that takes an array of full names in the format:

LastName FirstName MiddleName

and creates a new array containing:

FirstName LastName

The middle name is ignored.

C++ solution using vector<string>

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

vector<string> convertNames(const vector<string>& names) {
    vector<string> result;

    for (const string& fullName : names) {
        string lastName, firstName, middleName;

        // Split the string into three parts
        stringstream ss(fullName);
        ss >> lastName >> firstName >> middleName;

        // Create "First Name Last Name"
        result.push_back(firstName + " " + lastName);
    }

    return result;
}

int main() {
    vector<string> names = {
        "Smith John Michael",
        "Brown Alice Marie",
        "Johnson David Robert",
        "Wilson Sarah Ann"
    };

    vector<string> result = convertNames(names);

    cout << "New array:\n";

    for (const string& name : result) {
        cout << name << endl;
    }

    return 0;
}

Output

New array:
John Smith
Alice Brown
David Johnson
Sarah Wilson

Explanation step by step

1. Function definition

vector<string> convertNames(const vector<string>& names)

The function receives an array of strings:

vector<string>

and returns another vector<string>.

We use:

const vector<string>&

because we don’t need to modify the original array.

2. Create the new array

vector<string> result;

This will store the converted names.

For example:

John Smith
Alice Brown
David Johnson

3. Process every name

for (const string& fullName : names)

This goes through each string in the input array.

For example:

"Smith John Michael"

4. Create variables for the three names

string lastName, firstName, middleName;

We need three variables because the input has three parts:

Last Name | First Name | Middle Name

5. Split the string

stringstream ss(fullName);
ss >> lastName >> firstName >> middleName;

For:

Smith John Michael

we get:

lastName  = "Smith"
firstName = "John"
middleName = "Michael"

stringstream is useful because the names are separated by spaces.

6. Create the new format

result.push_back(firstName + " " + lastName);

We combine:

First Name + space + Last Name

So:

John + " " + Smith

becomes:

John Smith

The middle name is simply not added.

7. Return the new array

return result;

The function returns the newly created array.

If your assignment specifically requires a traditional array

If your teacher hasn’t introduced vector yet and requires a dynamically allocated array, you can use this version:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

string* convertNames(string names[], int n) {
    string* result = new string[n];

    for (int i = 0; i < n; i++) {
        string lastName, firstName, middleName;

        stringstream ss(names[i]);
        ss >> lastName >> firstName >> middleName;

        result[i] = firstName + " " + lastName;
    }

    return result;
}

int main() {
    string names[] = {
        "Smith John Michael",
        "Brown Alice Marie",
        "Johnson David Robert"
    };

    int n = 3;

    string* result = convertNames(names, n);

    cout << "New array:\n";

    for (int i = 0; i < n; i++) {
        cout << result[i] << endl;
    }

    delete[] result;

    return 0;
}

This second version is closer to the wording “input is an array of strings and its length”, while the vector version is safer and more modern C++.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?


Explore More IT Terms


Share this term: Facebook X LinkedIn WhatsApp Email

Leave a Reply

Your email address will not be published. Required fields are marked *