Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c++.moderated    |    Moderated discussion of C++ superhackery    |    33,346 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 32,156 of 33,346    |
|    Ulrich Eckhardt to All    |
|    Re: Find/replace function    |
|    18 Apr 12 05:02:00    |
   
   0034716b   
   From: ulrich.eckhardt@dominolaser.com   
      
   Am 18.04.2012 02:05, schrieb Jimmy H.:   
   > string replace(const string &input,   
   > const string &to_find,   
   > const string &replacement) {   
   > auto end = input.end();   
   > string result;   
   > for(auto it = input.begin(); it < end; it++) {   
   > if(*it == to_find[0] && equal(to_find.begin(),   
   > to_find.end(),   
   > it)) {   
   > result += replacement;   
   > it += to_find.length() - 1;   
   > } else {   
   > result += *it;   
   > }   
   > }   
   > return result;   
   > }   
   [...]   
   > Three questions:   
   > (a) Are there any glaring (or even not glaring) inefficiencies   
      
   There are a few:   
   1. You repeatedly re-allocate the storage for the result string while   
   concatenating. I would simply assume that the output size is roughly the   
   input size and preallocate the same amount of storage. First scanning   
   for to_fing and from that determining the exact size is also something   
   worth testing, but scanning the sequence twice could eat up all the   
   benefits of not reallocating the storage.   
   2. You are rolling your own strstr() function basically and not reaping   
   the benefits of optimized implementations. For that reason, I wouldn't   
   use iterators but the index-based string functions. With that, just use   
   string::find() to locate the string. Then, append the whole piece   
   between the current position and where the string is found in one,   
   instead of adding each character separately. Make sure you have tests in   
   place for this, it's easy to miss corner cases.   
   3. You return by value. Most compilers will get this right and optimize   
   it out.   
   4. I don't understand why you are skipping "to_find.length() - 1" steps   
   forward. The sequence [it, it+length) is exactly equal to to_find, so   
   the next possible occurrence is at it+length. Add a tests that replaces   
   the string "fouf" with "barb" inside "foufouf". You must get "barbouf"   
   as result!   
      
   Note: Since you are after the performance, you need benchmarks, no way   
   around this.   
      
      
   > points of bad style in this implementation?   
      
   1. Even for strings, I would use size() instead of length().   
   2. Use prefix increment (++it) instead of postfix increment (it++).   
   3. Use equality comparison (it!=end) instead of less-than (it
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca