Search code examples
stringstlstl-algorithmstd

Reversing words of a string inplace using STL


This question has been done to death in SO:. Here is my version using STL functions of the tradition algorithm of reversing the string and then reversing the words. is there a more elegant soln without using loops?

std::string something;
std::getline(std::cin, something);
std::reverse(something.begin(), something.end());
for (size_t i = 0, size_t nextPos = something.find_first_of(' ', i);
     nextPos != std::string::npos; i = nextPos + 1, 
     nextPos = something.find_first_of(' ', i)) {
     std::string::iterator startIter = something.begin() + i;
     std::string::iterator endIter = something.begin() + nextPos;
     std::reverse(startIter, endIter);
}

Assume the input is perfect no space before and after sentence and exactly single space between words. Is there an stl solution that requires no loop?

Best, Subramanian


Solution

  • Here's a loop-free way using iterators and a closure:

    #include <iterator>
    #include <algorithm>
    #include <sstream>
    #include <string>
    
    std::istringstream iss(something);
    std::string sentence;
    
    std::for_each(std::istream_iterator<std::string>(iss),
                  std::istream_iterator<std::string>(),
                  [&sentence](std::string const & s) { sentence.insert(0, s + ' '); }
                 );
    

    Update: Here is an in-place algorithm with one single loop:

    #include <string>
    #include <algorithm>
    
    void reverse(std::string & s)
    {
        for (std::size_t pos, done = 0;
             (pos = s.find(' ')) != s.npos && ++pos + done <= s.size();
             done += pos)
        {
            std::rotate(s.begin(), s.begin() + pos, s.end() - done);
        }
    }
    

    Example:

    #include <iostream>
    
    int main()
    {
        for (std::string line; std::getline(std::cin, line); )
        {
            reverse(line);
            std::cout << '"' << line << '"' << std::endl;
        }
    }
    

    Test run:

    $ echo "hello world how are you " | ./prog
    "you are how world hello "