From 6303fa99c478c20125b6f5d2b1b2e04bc7b9b5a8 Mon Sep 17 00:00:00 2001 From: Matthias Rahlf Date: Fri, 16 Oct 2026 21:58:51 +0200 Subject: [PATCH 1/3] reverse-string: Replace `append` with `push_back` The code and description of the "Approach: Iterative" and "Approach: Linear Recursion" were incorrect. They did use the member function `std::string::append(char)` which does not exist. Replace it with `push_back(char)` and adjust the description. --- .../practice/reverse-string/.approaches/introduction.md | 2 +- .../reverse-string/.approaches/iterative/content.md | 6 +++--- .../reverse-string/.approaches/iterative/snippet.txt | 2 +- .../reverse-string/.approaches/linear-recursion/content.md | 6 +++--- .../reverse-string/.approaches/linear-recursion/snippet.txt | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/exercises/practice/reverse-string/.approaches/introduction.md b/exercises/practice/reverse-string/.approaches/introduction.md index 90fe7bf20..4a872a1c9 100644 --- a/exercises/practice/reverse-string/.approaches/introduction.md +++ b/exercises/practice/reverse-string/.approaches/introduction.md @@ -155,7 +155,7 @@ void recursive_helper(std::string_view input, std::string& output) return; // append the last character of the input to the output - output.append(input.back()); + output.push_back(input.back()); // and remove that last character from the input input.remove_suffix(1); diff --git a/exercises/practice/reverse-string/.approaches/iterative/content.md b/exercises/practice/reverse-string/.approaches/iterative/content.md index 06fe6f687..adbcea5ba 100644 --- a/exercises/practice/reverse-string/.approaches/iterative/content.md +++ b/exercises/practice/reverse-string/.approaches/iterative/content.md @@ -31,7 +31,7 @@ std::string reverse_string(const std::string& original) std::size_t rindex = size(original) - i - 1; // (4) append each character (starting from the end) - result.append(original[rindex]); + result.push_back(original[rindex]); } // result now contains a reversed version of the string @@ -84,8 +84,8 @@ for (auto rit = rbegin(original); rit != rend(original); ++rit) ## Appending to the result -The solution above uses the member function `append` (see [cppreference.com][cppref-string-append].) -There are other equivalent member function like `push_back()` (see [cppreference.com][cppref-string-pushback]) or the operator `+=` (see [cppreference.com][cppref-string-operator-plus-equal].) +The solution above uses the member function `push_back` (see [cppreference.com][cppref-string-pushback].) +Alternatives include the operator `+=` (see [cppreference.com][cppref-string-operator-plus-equal]) or the member function `append()` (with the count of `1` as an additional argument, see [cppreference.com][cppref-string-append].) Either one is fine, chosing one is a matter of personal preferences. ## Variation: With assignments diff --git a/exercises/practice/reverse-string/.approaches/iterative/snippet.txt b/exercises/practice/reverse-string/.approaches/iterative/snippet.txt index b01c658e0..9344c39f3 100644 --- a/exercises/practice/reverse-string/.approaches/iterative/snippet.txt +++ b/exercises/practice/reverse-string/.approaches/iterative/snippet.txt @@ -2,6 +2,6 @@ std::string result; for (std::size_t i = 0; i < size(original); ++i) { std::size_t rindex = size(original) - i - 1; - result.append(original[rindex]); + result.push_back(original[rindex]); } return result; diff --git a/exercises/practice/reverse-string/.approaches/linear-recursion/content.md b/exercises/practice/reverse-string/.approaches/linear-recursion/content.md index a3831e83a..9e635cb88 100644 --- a/exercises/practice/reverse-string/.approaches/linear-recursion/content.md +++ b/exercises/practice/reverse-string/.approaches/linear-recursion/content.md @@ -28,7 +28,7 @@ void recursive_helper(std::string_view input, std::string& output) return; // (4) append the last character of the input to the output - output.append(input.back()); + output.push_back(input.back()); // and "remove" the last character from the input input.remove_suffix(1); @@ -66,8 +66,8 @@ In that case nothing needs to be done. `std::string_view` has the member function `back` that returns the last character (see [cppreference.com][cppref-stringview-back]). -`std::string` has the member function `append` that appends something to the string (see [cppreference.com][cppref-string-append]). -There are equivalent member functions like `push_back` (see [cppreference.com][cppref-string-pushback]) or the operator `+=` (see [cppreference.com][cppref-string-operator-plus-assign]). +`std::string` has the member function `push_back` that appends a character to the string (see [cppreference.com][cppref-string-pushback]). +There are equivalent member functions like `append` (with the count as an additional argument, see [cppreference.com][cppref-string-append]) or the operator `+=` (see [cppreference.com][cppref-string-operator-plus-assign]). In this case they do exactly the same. `std::string_view` has the member function `remove_suffix` that *conceptually* removes some characteas from the end of the `std::string_view`. diff --git a/exercises/practice/reverse-string/.approaches/linear-recursion/snippet.txt b/exercises/practice/reverse-string/.approaches/linear-recursion/snippet.txt index 036e8a138..b365a606b 100644 --- a/exercises/practice/reverse-string/.approaches/linear-recursion/snippet.txt +++ b/exercises/practice/reverse-string/.approaches/linear-recursion/snippet.txt @@ -2,7 +2,7 @@ void recursive_helper(std::string_view input, std::string& output) { if (input.empty()) return; - output.append(input.back()); + output.push_back(input.back()); input.remove_suffix(1); recursive_helper(input, output); } From 0a28e20ebd0abba24c7fae836be4c7b4aa0592d0 Mon Sep 17 00:00:00 2001 From: Matthias Rahlf Date: Fri, 16 Oct 2026 22:04:58 +0200 Subject: [PATCH 2/3] reverse-string: Fix divide-and-conquer code The code in "Approach: Divide and conquer" was incorrect, it did use an invalid parameter name and closing parentheses were missing. --- .../.approaches/divide-and-conquer/content.md | 6 +++--- .../.approaches/divide-and-conquer/snippet.txt | 6 +++--- .../practice/reverse-string/.approaches/introduction.md | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md b/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md index 6c45a8b84..568335741 100644 --- a/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md +++ b/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md @@ -27,9 +27,9 @@ std::string reverse_string(std::string_view original) return std::string{original}; // "divide and conquer" by reversing the two halfs of the string separately - auto half_size = size(str) / 2; - return reverse_string(original.substr(half_size) + - reverse_string(original.substr(0, half_size); + auto half_size = size(original) / 2; + return reverse_string(original.substr(half_size)) + + reverse_string(original.substr(0, half_size)); } } // namespace reverse_string; diff --git a/exercises/practice/reverse-string/.approaches/divide-and-conquer/snippet.txt b/exercises/practice/reverse-string/.approaches/divide-and-conquer/snippet.txt index c66fde6e2..a40b58b43 100644 --- a/exercises/practice/reverse-string/.approaches/divide-and-conquer/snippet.txt +++ b/exercises/practice/reverse-string/.approaches/divide-and-conquer/snippet.txt @@ -1,5 +1,5 @@ if (size(original) <= 1) return std::string{original}; -auto half_size = size(str) / 2; -return reverse_string(original.substr(half_size) + - reverse_string(original.substr(0, half_size); +auto half_size = size(original) / 2; +return reverse_string(original.substr(half_size)) + + reverse_string(original.substr(0, half_size)); diff --git a/exercises/practice/reverse-string/.approaches/introduction.md b/exercises/practice/reverse-string/.approaches/introduction.md index 4a872a1c9..5f53e4356 100644 --- a/exercises/practice/reverse-string/.approaches/introduction.md +++ b/exercises/practice/reverse-string/.approaches/introduction.md @@ -194,9 +194,9 @@ std::string reverse_string(std::string_view original) return std::string{original}; // "divide and conquer" by reversing the two halfs of the string separately - auto half_size = size(str) / 2; - return reverse_string(original.substr(half_size) + - reverse_string(original.substr(0, half_size); + auto half_size = size(original) / 2; + return reverse_string(original.substr(half_size)) + + reverse_string(original.substr(0, half_size)); } ``` From 91db56c743d5b6a2a23725962b8f7115bc4fb68a Mon Sep 17 00:00:00 2001 From: Matthias Rahlf Date: Fri, 16 Oct 2026 22:16:49 +0200 Subject: [PATCH 3/3] reverse-string: Fix small errors in descriptions Remove unnecessary semicolons in comments. Fix plural-s errors. Replace "you" with an inclusive "we". Fix name of cppreference link. --- .../.approaches/direct-construction/content.md | 2 +- .../.approaches/divide-and-conquer/content.md | 4 ++-- .../reverse-string/.approaches/iterative/content.md | 6 +++--- .../.approaches/linear-recursion/content.md | 2 +- .../.approaches/over-engineered/content.md | 10 +++++----- .../.approaches/stack-operations/content.md | 6 +++--- .../.approaches/swapping-characters/content.md | 2 +- .../.approaches/using-the-standard-lib/content.md | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/exercises/practice/reverse-string/.approaches/direct-construction/content.md b/exercises/practice/reverse-string/.approaches/direct-construction/content.md index b1ebc8ad2..82a3b557b 100644 --- a/exercises/practice/reverse-string/.approaches/direct-construction/content.md +++ b/exercises/practice/reverse-string/.approaches/direct-construction/content.md @@ -27,7 +27,7 @@ std::string reverse_string(std::string_view original) return std::string(rbegin(original), rend(original)); } -} // namespace reverse_string; +} // namespace reverse_string ``` ## The type of the parameter diff --git a/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md b/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md index 568335741..aa38b023a 100644 --- a/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md +++ b/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md @@ -32,7 +32,7 @@ std::string reverse_string(std::string_view original) reverse_string(original.substr(0, half_size)); } -} // namespace reverse_string; +} // namespace reverse_string ``` ## The type of the parameter @@ -75,7 +75,7 @@ We divide the problem into smaller problems, then we "conquer" (solve) them inde Calculating the `half_size` and splitting the string into two parts takes constant time (due to the `std::string_view`). Each recursive function call handles one half of the string. -Combining the two reversed half at the end takes linear time. +Combining the two reversed halves at the end takes linear time. Therefore the runtime complexity of this implementation is O(n log n), it is "linearithmic" (see the [Wikipedia][wiki-quasilinear-time]). Note that in contrast to the [Linear Recursion][approach-linear-recursion] this approach is safe. diff --git a/exercises/practice/reverse-string/.approaches/iterative/content.md b/exercises/practice/reverse-string/.approaches/iterative/content.md index adbcea5ba..ae58357e8 100644 --- a/exercises/practice/reverse-string/.approaches/iterative/content.md +++ b/exercises/practice/reverse-string/.approaches/iterative/content.md @@ -38,7 +38,7 @@ std::string reverse_string(const std::string& original) return result; } -} // namespace reverse_string; +} // namespace reverse_string ``` ## The type of the parameter @@ -47,7 +47,7 @@ The function takes its argument "by reference to const" (`const std::string&`). That avoids creating an unnecessary copy which can be comparatively expensive for a `std::string`. This is a best practice and widely recommended if a copy is expensive and the function does not need a "working copy" that it can modify (see the [C++ Core Guidelines][cgl-by-value-by-const-ref].) -Alternatively you could use a `std::string_view`. +Alternatively we could use a `std::string_view`. That type was added to C++17, it is an immutable view of a string, it is cheap to construct and to copy (see [cppreference.com][cppref-stringview].) ## Constructing an empty `std::string` @@ -116,7 +116,7 @@ for (std::size_t i = 0, rindex = size(original) - 1; i < size(original); ++i, -- This is a valid approach, it produces a correct result and is reasonably efficient. But most experts recommend not doing things "manually" if there are better alternatives. -You could consider using the `std::string` class to construct the reversed string directly. +We could consider using the `std::string` class to construct the reversed string directly. That would shorten the code, would be concise, easy to read, idiomatic, and very efficient. Check out the [Direct Construction][approach-direct-construction] approach. diff --git a/exercises/practice/reverse-string/.approaches/linear-recursion/content.md b/exercises/practice/reverse-string/.approaches/linear-recursion/content.md index 9e635cb88..a73e43e36 100644 --- a/exercises/practice/reverse-string/.approaches/linear-recursion/content.md +++ b/exercises/practice/reverse-string/.approaches/linear-recursion/content.md @@ -43,7 +43,7 @@ std::string reverse_string(std::string_view original) return result; } -} // namespace reverse_string; +} // namespace reverse_string ``` ## The types of the parameters diff --git a/exercises/practice/reverse-string/.approaches/over-engineered/content.md b/exercises/practice/reverse-string/.approaches/over-engineered/content.md index 14fac602f..435196b79 100644 --- a/exercises/practice/reverse-string/.approaches/over-engineered/content.md +++ b/exercises/practice/reverse-string/.approaches/over-engineered/content.md @@ -48,7 +48,7 @@ std::string reverse_string(const char *str) return reverse_string(std::string_view{str}); } -} // namespace reverse_string; +} // namespace reverse_string ``` ## The `[[nodiscard]]` attribute @@ -60,10 +60,10 @@ That is helpful in situations where either the result contains some error code t ## Overloading functions -In C++ it is possible (and quite common) to define multiple different functions with the same name but different parameter (different number of parameter or different parameter types.) -When an overloaded function is called the compiler collects all candidate with that name, trims the set of candidate to the *viable* ones, and then selects the best fit for the function call (see [cppreference.com][cppref-overload-resolution]). +In C++ it is possible (and quite common) to define multiple functions with the same name but different parameters (different number of parameters or different parameter types.) +When an overloaded function is called the compiler collects all candidates with that name, trims the set of candidates to the *viable* ones, and then selects the best fit for the function call (see [cppreference.com][cppref-overload-resolution]). -Overloading function is often done if these functions perform the same task *conceptually* but in a slightly different way, depending on the arguments. +Overloading functions is often done if these functions perform the same task *conceptually* but in a slightly different way, depending on the arguments. ## Handling a `std::string` rvalue @@ -80,7 +80,7 @@ In that case the program does not have to allocate memory for the reversed versi The first overload (that takes an rvalue reference) does not allocate any memory dynamically, we know for sure that no exceptions can occur. With `noexcept` that can be formally specified (see [cppreference.com][cppref-noexcept].) -That can allows the compiler to generate better instructions when the function is called. +That can allow the compiler to generate better instructions when the function is called. ## Calling `std::reverse` diff --git a/exercises/practice/reverse-string/.approaches/stack-operations/content.md b/exercises/practice/reverse-string/.approaches/stack-operations/content.md index 7b78ccfcc..33c4a57d4 100644 --- a/exercises/practice/reverse-string/.approaches/stack-operations/content.md +++ b/exercises/practice/reverse-string/.approaches/stack-operations/content.md @@ -38,7 +38,7 @@ std::string reverse_string(std::string_view original) return result; } -} // namespace reverse_string; +} // namespace reverse_string ``` ## The type of the parameter @@ -68,7 +68,7 @@ In programming and computer science "stack" is a term for a container that suppo - You can *pop* the top-most (i.e. most recently pushed) item off the stack. - You can *peek* at the top-most item (without popping it off the stack). -`std::string_view` have the member functions `back` (see [cppreference.com][cppref-stringview-back]) and `remove_suffix` (see [cppreference.com][cppref-string-removesuffix]). +`std::string_view` have the member functions `back` (see [cppreference.com][cppref-stringview-back]) and `remove_suffix` (see [cppreference.com][cppref-stringview-removesuffix]). `std::string` has the member function `push_back` (see [cppreference.com][cppref-string-pushback]). They let use use the two strings like stacks. @@ -87,5 +87,5 @@ It is mostly presented as an interesting idea and unique way to think about the [cppref-stringview]: https://en.cppreference.com/w/cpp/string/basic_string_view [wiki-stack]: https://en.wikipedia.org/wiki/Stack_(abstract_data_type) [cppref-stringview-back]: https://en.cppreference.com/w/cpp/string/basic_string_view/back -[cppref-string-removesuffix]: https://en.cppreference.com/w/cpp/string/basic_string_view/remove_suffix +[cppref-stringview-removesuffix]: https://en.cppreference.com/w/cpp/string/basic_string_view/remove_suffix [cppref-string-pushback]: https://en.cppreference.com/w/cpp/string/basic_string/push_back diff --git a/exercises/practice/reverse-string/.approaches/swapping-characters/content.md b/exercises/practice/reverse-string/.approaches/swapping-characters/content.md index 7369dd2ba..989040eed 100644 --- a/exercises/practice/reverse-string/.approaches/swapping-characters/content.md +++ b/exercises/practice/reverse-string/.approaches/swapping-characters/content.md @@ -44,7 +44,7 @@ std::string reverse_string(std::string str) return str; } -} // namespace reverse_string; +} // namespace reverse_string ``` ## The type of the parameter diff --git a/exercises/practice/reverse-string/.approaches/using-the-standard-lib/content.md b/exercises/practice/reverse-string/.approaches/using-the-standard-lib/content.md index b0c63339c..ac7fac9ce 100644 --- a/exercises/practice/reverse-string/.approaches/using-the-standard-lib/content.md +++ b/exercises/practice/reverse-string/.approaches/using-the-standard-lib/content.md @@ -31,7 +31,7 @@ std::string reverse_string(std::string str) return str; } -} // namespace reverse_string; +} // namespace reverse_string ``` ## Including the header