Denis319199
Denis319199

Reputation: 288

Optimize the trimming function

There is the void TrimRight( char *s ) function, which has a very long s-style string as an argument. A passed string consists of a lot of white spaces after a last word and, also, throughout its length. It is required that the function is to trim excess white spaces at the right.

I suggested an implementation looking like this:

void TrimRight(char *str) {
    char *space_pos{};  // last space position
    auto iterator{str}; // string iterator
    while (*iterator != '\0') {
      if (*iterator == ' ') { // save first space
        if (!space_pos) {
          space_pos = iterator;
        }
      } else {
        space_pos = nullptr;
      }
      ++iterator;
    }
    if (space_pos) { // if the string does not end with alpha
      *space_pos = '\0';
    }   
}

It works pretty well but N memory accesses seems excess, since the task given to me points out that a string is very long and contains many white spaces. Therefore, the question have been raised: Is there a way to refine the function in order to decrease a number of memory accesses?

Upvotes: 2

Views: 258

Answers (1)

Ted Lyngmo
Ted Lyngmo

Reputation: 117432

You never know where you may find a non-space character so you do have to look through the whole string.

You could do it with a lot less comparisons though.

Example:

void TrimRight(char *iterator) {
    for(;; ++iterator) {
        // Loop for as long as the string has not ended and non-space chars are
        // found.
        for(;*iterator != ' '; ++iterator) {
            // Return if the end of the string is found. If the end of the string
            // is found here, it did not end with spaces.
            if(*iterator == '\0') return;
        }

        // A space position is found, store it.
        char* space_pos = iterator;

        // Loop for as long as there are spaces.
        do ++iterator; while(*iterator == ' ');

        // Return if the end of the string is found. If the end of the string
        // is found at this stage, it ended with spaces so trim the string.
        if(*iterator == '\0') {
            *space_pos = '\0';
            return;
        }
    }
}

Note: You mention whitespaces in your text but you only test for spaces. If you really need to trim away all trailing whitespaces, replace the comparisons with ' ' above with std::isspace() tests, like this:

for(;!std::isspace(*iterator); ++iterator) {

and

do ++iterator; while(std::isspace(*iterator));

Upvotes: 2

Related Questions