Synthwave09
Synthwave09

Reputation: 79

Most efficient way to move last n chars to another string

This is in a way related to my other question.

My task is to take last times characters of string str and add them to string removed, and to remove those characters from str.

My idea was to do one memory allocation, iterate over times characters of str one time. That's what I am doing in the code below, assigning to removed index by index and popping from str per iteration.

int times = std::stoi(arg); // arg is const std::string &        
std::string removed;
removed.resize(times); 
while (times > 0)
{
    removed[times-1] = str.back();
    str.pop_back();
    --times;
}

Question: what is the most efficient (without excessive copying, iterating several times, etc.) and elegant way to do this?

Upvotes: 1

Views: 203

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

I'd probably use substr and resize:

if(str.size() >= times) {
    std::string removed = str.substr(str.size() - times);
    str.resize(str.size() - times);
}

Then again, if you don't actually need the resulting strings to be mutable, a very efficient approach would be to create std::string_views over the original str and leave str unchanged. std::string_views are really cheap. They typically consist of only a pointer and a length and doesn't do any dynamic memory allocation. Note though that str must "outlive" the views since it's str that owns the actual memory.

if(str.size() >= times) {
    std::string_view vStr(str.begin(), str.end() - times);
    std::string_view vRemoved(str.end() - times, str.end());
       
    std::cout << vStr << '\n';
    std::cout << vRemoved << '\n';
}    

Upvotes: 3

NathanOliver
NathanOliver

Reputation: 180500

I would do some checking before hand to make sure times <= str.size() but as long as it is this can be done pretty simple using append and erase like

removed.append(str.end() - times, str.end()); // adds the end of str to removed
str.erase(str.end() - times, str.end()); // removes the end from str

Upvotes: 4

Related Questions