C++ Arrays and Strings

Reverse a string

Description: Reverse "C++ Rocks".

Hint:

  • std::reverse is in <algorithm>. A string can also be built from rbegin() and rend().

Solution

#include <algorithm>
#include <iostream>
#include <string>

int main() {
    std::string s = "C++ Rocks";

    std::string a;
    for (int i = static_cast<int>(s.size()) - 1; i >= 0; i--) a += s[i];

    std::string b = s;
    std::reverse(b.begin(), b.end());

    std::string c(s.rbegin(), s.rend());
    std::cout << a << '\n' << b << '\n' << c << '\n';
}
Output

skcoR ++C
skcoR ++C
skcoR ++C

How it works

  • The three ways give the same result. The library way is the shortest and the clearest.

Read C++ Strings.

Check if a string is a palindrome

Description: Write is_palindrome(std::string). Ignore the case and the spaces. Test “Madam”, “Nurses run” and “C++”.

Hint:

  • Clean the text, then compare it with its reverse.

Solution

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

bool is_palindrome(std::string s) {
    std::erase_if(s, [](unsigned char c) { return !std::isalnum(c); });
    std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); });
    return std::equal(s.begin(), s.begin() + s.size() / 2, s.rbegin());
}

int main() {
    std::cout << std::boolalpha;
    for (std::string t : {"Madam", "Nurses run", "C++"}) {
        std::cout << t << " -> " << is_palindrome(t) << '\n';
    }
}
Output

Madam -> true
Nurses run -> true
C++ -> true

How it works

  • We remove everything which is not a letter or digit, and make the rest lower case.
  • std::equal compares the first half with the reversed second half.

Read C++ Strings.

Count the vowels in a string

Description: Count the vowels and the consonants in "Learn C++ Programming".

Hint:

  • Use std::isalpha and look for the letter in "aeiou".

Solution

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

int main() {
    std::string text = "Learn C++ Programming";
    int vowels = 0, consonants = 0;
    for (unsigned char c : text) {
        if (!std::isalpha(c)) continue;
        if (std::string("aeiou").find(static_cast<char>(std::tolower(c))) != std::string::npos) vowels++;
        else consonants++;
    }
    std::cout << "Vowels: " << vowels << ", consonants: " << consonants << '\n';
}
Output

Vowels: 5, consonants: 12

How it works

  • Spaces, + signs and other characters are skipped with continue.

Read C++ Strings.

Find the second largest number in a vector

Description: Find the second largest number in {12, 35, 1, 10, 34, 1} without sorting.

Hint:

  • Keep largest and second, and update both in one loop.

Solution

#include <climits>
#include <iostream>
#include <vector>

int second_largest(const std::vector<int>& v) {
    int largest = INT_MIN, second = INT_MIN;
    for (int n : v) {
        if (n > largest) {
            second = largest;
            largest = n;
        } else if (n > second && n != largest) {
            second = n;
        }
    }
    return second;
}

int main() {
    std::cout << second_largest({12, 35, 1, 10, 34, 1}) << '\n';
    std::cout << second_largest({5, 5, 5, 2}) << '\n';
}
Output

34
2

How it works

  • When a bigger value comes, the old biggest becomes the second one.

Read C++ Vectors.

Sort a vector with bubble sort

Description: Sort {64, 34, 25, 12, 22, 11, 90} without std::sort, then check the result with std::sort.

Hint:

  • Swap neighbours which are in the wrong order. Repeat.

Solution

#include <algorithm>
#include <iostream>
#include <vector>

void bubble_sort(std::vector<int>& a) {
    for (std::size_t i = 0; i + 1 < a.size(); i++) {
        bool swapped = false;
        for (std::size_t j = 0; j + 1 < a.size() - i; j++) {
            if (a[j] > a[j + 1]) {
                std::swap(a[j], a[j + 1]);
                swapped = true;
            }
        }
        if (!swapped) break;
    }
}

int main() {
    std::vector<int> data = {64, 34, 25, 12, 22, 11, 90};
    auto check = data;
    bubble_sort(data);
    std::sort(check.begin(), check.end());
    for (int x : data) std::cout << x << ' ';
    std::cout << '\n' << (data == check) << '\n';
}
Output

11 12 22 25 34 64 90
1

How it works

  • After every round of the outer loop, the biggest remaining item is in its place.
  • It is slow (O(n squared)). Real code uses std::sort.

Read C++ Vectors.

Transpose a matrix

Description: Transpose {{1,2,3},{4,5,6}} to {{1,4},{2,5},{3,6}}.

Hint:

  • The new matrix has cols rows and rows columns: t[j][i] = m[i][j].

Solution

#include <iostream>
#include <vector>

using Matrix = std::vector<std::vector<int>>;

Matrix transpose(const Matrix& m) {
    std::size_t rows = m.size(), cols = m[0].size();
    Matrix t(cols, std::vector<int>(rows));
    for (std::size_t i = 0; i < rows; i++)
        for (std::size_t j = 0; j < cols; j++)
            t[j][i] = m[i][j];
    return t;
}

int main() {
    for (const auto& row : transpose({{1, 2, 3}, {4, 5, 6}})) {
        for (int v : row) std::cout << v << ' ';
        std::cout << '\n';
    }
}
Output

1 4
2 5
3 6

How it works

  • A 2 x 3 matrix gives a 3 x 2 matrix, so the new vector has the sizes swapped.

Read C++ Vectors.