I was recently in a C++ technical interview, where I was given a bit of simple string manipulation code, which is intended to take a string and return a string that is comprised of the first and last n-characters, and then proceed to correct any bugs and to also make the function as efficient as possible, I came up with the solution below, however the interviewer claimed there was an even faster more optimal way:
Original code:
std::string first_last_n(int n, std::string s)
{
std::string first_n = s.substr(0,n);
std::string last_n = s.substr(s.size()-n-1,n);
return first_n + last_n;
}
My code:
bool first_last_n(const std::size_t& n, const std::string& s, std::string& r)
{
if (s.size() < n)
return false;
r.reserve(2 * n);
r.resize(0);
r.append(s.data(),s.data() + n);
r.append(s.data() + (s.size() - n), s.data() + s.size());
return true;
}
Summary of my changes:
Changed the interface to take a return string as reference (assuming RVO and rvalues are not available yet)
Removed temporary strings being constructed via substr
Passed input string as a const reference inorder to get around temporary instantiation of input
Fixed off-by-1 error in last_n string
Reduced the number of times each character is touched down to once, or twice (in the event of an overlapping scenario)
Placed a check in the event the string s's size is less than n, returning false for failure.
Assuming only native C++ is allowed, is there some other way of doing the above more efficiently or optimally?
Note 1: The original input string instance is not to be modified.
Note 2: All solutions must pass the following test case, otherwise they are not valid.
void test()
{
{
std::string s = "0123456789";
std::string r = first_last_n(10,s);
assert(r == "01234567890123456789");
}
{
std::string s = "0123456789ABC0123456789";
std::string r = first_last_n(10,s);
assert(r == "01234567890123456789");
}
{
std::string s = "1234321";
std::string r = first_last_n(5,s);
assert(r == "1234334321");
}
}
Times:
Note: Timing specifically tests "long" strings. I.e. those where short string optimization is not used. (My strings were 100 length).