I recently posted an answer to this SO question this SO question as I did not think any of the current answers were satisfactory (most don't even answer the question!). I was wondering if anyone could offer any improvements on my solution to this problem? I'm most interested in performance here. Also note this algorithm does not require any additional copies of the input string (if passed an r-value), ideally I'd like to keep this property.
I recently posted an answer to this SO question as I did not think any of the current answers were satisfactory (most don't even answer the question!). I was wondering if anyone could offer any improvements on my solution to this problem? I'm most interested in performance here. Also note this algorithm does not require any additional copies of the input string (if passed an r-value), ideally I'd like to keep this property.
I recently posted an answer to this SO question as I did not think any of the current answers were satisfactory (most don't even answer the question!). I was wondering if anyone could offer any improvements on my solution to this problem? I'm most interested in performance here. Also note this algorithm does not require any additional copies of the input string (if passed an r-value), ideally I'd like to keep this property.
Current improvements
Here's an updated version incorporating suggested improvements:
#include <string>
std::string repeat(std::string str, const std::size_t n)
{
if (n == 0) {
str.clear();
str.shrink_to_fit();
return str;
}
if (n == 1 || str.empty()) return str;
const auto period_size = str.size();
if (period_size == 1) {
str.append(n - 1, str.front());
return str;
}
str.reserve(period_size * n);
std::size_t m {2};
for (; m < n; m *= 2) str += str;
str.append(str.c_str(), (n - (m / 2)) * period_size);
return str;
}
Current improvements
Here's an updated version incorporating suggested improvements:
#include <string>
std::string repeat(std::string str, const std::size_t n)
{
if (n == 0) {
str.clear();
str.shrink_to_fit();
return str;
}
if (n == 1 || str.empty()) return str;
const auto period_size = str.size();
if (period_size == 1) {
str.append(n - 1, str.front());
return str;
}
str.reserve(period_size * n);
std::size_t m {2};
for (; m < n; m *= 2) str += str;
str.append(str.c_str(), (n - (m / 2)) * period_size);
return str;
}
Current improvements
Here's an updated version incorporating suggested improvements:
#include <string>
std::string repeat(std::string str, const std::size_t n)
{
if (n == 0) {
str.clear();
str.shrink_to_fit();
return str;
}
if (n == 1 || str.empty()) return str;
const auto period_size = str.size();
if (period_size == 1) {
str.append(n - 1, str.front());
return str;
}
str.reserve(period_size * n);
std::size_t m {2};
for (; m < n; m *= 2) str += str;
str.append(str.c_str(), (n - (m / 2)) * period_size);
return str;
}
Current improvements
Here's an updated version incorporating suggested improvements:
#include <string>
std::string repeat(std::string str, const std::size_t n)
{
if (n == 0) {
str.clear();
str.shrink_to_fit();
return str;
}
if (n == 1 || str.empty()) return str;
const auto period_size = str.size();
if (period_size == 1) {
str.append(n - 1, str.front());
return str;
}
str.reserve(period_size * n);
std::size_t m {2};
for (; m < n; m *= 2) str += str;
str.append(str.c_str(), (n - (m / 2)) * period_size);
return str;
}