Skip to main content
added 7 characters in body
Source Link
Incomputable
  • 9.7k
  • 3
  • 34
  • 73

Well, Vincent covered almost everything as I was writing up alternative implementation... I'll just cover the rest then:

Don't leave your house without enabling warnings

Always compile with -Wall on Linux, and with alternative on Windows (IIRC it was /W4). This is one of the best advice messages ever made in C++ Q&A room. Link.

Well, Vincent covered everything as I was writing up alternative implementation... I'll just cover the rest then:

Don't leave your house without enabling warnings

Always compile with -Wall on Linux, and with alternative on Windows (IIRC it was /W4). This is one of the best advice messages ever made in C++ Q&A room. Link.

Well, Vincent covered almost everything as I was writing up alternative implementation... I'll just cover the rest then:

Source Link
Incomputable
  • 9.7k
  • 3
  • 34
  • 73

Well, Vincent covered everything as I was writing up alternative implementation... I'll just cover the rest then:

Don't leave your house without enabling warnings

Always compile with -Wall on Linux, and with alternative on Windows (IIRC it was /W4). This is one of the best advice messages ever made in C++ Q&A room. Link.

Do not make unqualified calls

Unqualified call is a non-member function call which doesn't have :: in front of to-be-called function name. Example:

std::sort(numbers.begin(), numbers.end()); //qualified
sort(numbers.begin(), numbers.end()); //unqualified

The latter can do something abysmally evil. If you don't know what ADL is, do not make unqualified calls.

Use iterators, possibly templated

Templates are not always a good thing, but using iterators is mostly a good thing. If one is tired of writing begin()/end() pair, one can just provide adapter interface for it.


Alternative implementation

When creating non-trivial algorithm, it is better to get a pen and something to write on. One can observe that there are only two parts to this algorithm:

  1. Copy into result until non-space is found

  2. Anchor on current position, find first space occurrence from anchor, then reverse copy into the result

The whole algorithm then looks like this:

while didn't reach end:
    execute 1)
    if reached end, break
    execute 2)

One can extract 1) and 2) into their own functions, but since they're trivial I didn't do so.


Code

#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

namespace rev {
    using iterator = std::string::const_iterator;
    
    std::string reverse_words(iterator first, iterator last) {
        std::string reversed_words(std::distance(first, last), '\0');
        auto d_first = reversed_words.begin();
        
        while (first != last) {
            while (first != last and *first ==' ')
                *d_first++ = *first++;
            if (first == last) break;
            
            auto word_anchor = first;
            while (first != last and *first != ' ')
                ++first;
            
            std::reverse_copy(word_anchor, first, d_first);
            d_first += std::distance(word_anchor, first);
        }
        return reversed_words;
    }
}

int main() {
    std::string words = "This is a bunch of words";
    auto reversed = rev::reverse_words(words.begin(), words.end());
    
    std::cout << reversed << '\n';
}

Demo.