diff --git a/exercises/practice/reverse-string/.approaches/direct-construction/content.md b/exercises/practice/reverse-string/.approaches/direct-construction/content.md index b1ebc8ad..82a3b557 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 6c45a8b8..aa38b023 100644 --- a/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md +++ b/exercises/practice/reverse-string/.approaches/divide-and-conquer/content.md @@ -27,12 +27,12 @@ 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; +} // 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/divide-and-conquer/snippet.txt b/exercises/practice/reverse-string/.approaches/divide-and-conquer/snippet.txt index c66fde6e..a40b58b4 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 90fe7bf2..5f53e435 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); @@ -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)); } ``` diff --git a/exercises/practice/reverse-string/.approaches/iterative/content.md b/exercises/practice/reverse-string/.approaches/iterative/content.md index 06fe6f68..ae58357e 100644 --- a/exercises/practice/reverse-string/.approaches/iterative/content.md +++ b/exercises/practice/reverse-string/.approaches/iterative/content.md @@ -31,14 +31,14 @@ 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 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` @@ -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 @@ -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/iterative/snippet.txt b/exercises/practice/reverse-string/.approaches/iterative/snippet.txt index b01c658e..9344c39f 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 a3831e83..a73e43e3 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); @@ -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 @@ -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 036e8a13..b365a606 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); } diff --git a/exercises/practice/reverse-string/.approaches/over-engineered/content.md b/exercises/practice/reverse-string/.approaches/over-engineered/content.md index 14fac602..435196b7 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 7b78ccfc..33c4a57d 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 7369dd2b..989040ee 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 b0c63339..ac7fac9c 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