0

I'm looking for replace all algorithm which replaced all occurrences of substring after specific position. So far I have replace all copy approach. What is most convenient way to do it without allocation of new string except this one? Does exist convenient way to do it with boost?

#include <iostream>
#include <string>
#include <boost/algorithm/string/replace.hpp>

int main() {
    std::string str = "1234 abc1234 marker 1234 1234 123 1 12 134 12341234";

    const std::string marker("marker"); 
    size_t pos = str.find(marker);
    if (pos == std::string::npos) {
        return 0;
    }
    pos += marker.length();
    std::string str_out(str, 0, pos);
    boost::algorithm::replace_all_copy(std::back_inserter(str_out), str.substr(pos, std::string::npos), "12", "XXXX");
    std::cout << str <<  std::endl;
    std::cout << str_out <<  std::endl;
}
Community
  • 1
  • 1
triclosan
  • 5,578
  • 6
  • 26
  • 50

1 Answers1

0

If you want to do an in-place find and replace operation, you'll have to be aware of the performance implications. In order to do such an operation, you will likely have to read the string backwards which can lead to bad cache behavior, or do a lot of memory shuffling, which can also be bad for performance. In general, it's best to do a replace-in-copy operation since any strings you'll be operating on will likely be relatively small, and most memory caches will handle things quite easily.

If you must have an in-place find and replace algorithm, use the following code if you're just looking for a drop-in function. I benchmarked it and it's very fast.

std::string& find_replace_in_place( std::string &haystack, const std::string needle, const std::string replacement, size_t start = 0 ){
    size_t ret = 0;
    size_t position = haystack.find( needle, start );
    while( position != std::string::npos ){
        haystack.replace( position, needle.length(), replacement );
        position = haystack.find( needle, position + replacement.length() );
    }
    return haystack;
}
Kaslai
  • 2,445
  • 17
  • 17