0

この質問はSO:で死ぬまで行われました。これは、文字列を反転してから単語を反転する従来のアルゴリズムのSTL関数を使用した私のバージョンです。ループを使用しない、よりエレガントなソルンはありますか?

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);
}

入力が完全であり、文の前後にスペースがなく、単語間にちょうど1つのスペースがあると仮定します。ループを必要としないstlソリューションはありますか?

最高の、サブラマニア人

4

1 に答える 1

2

イテレータとクロージャを使用したループのない方法は次のとおりです。

#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 + ' '); }
             );

更新:これは、単一のループを持つインプレースアルゴリズムです。

#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);
    }
}

例:

#include <iostream>

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

テスト走行:

$ echo "hello world how are you " | ./prog
"you are how world hello "
于 2012-10-13T21:10:53.883 に答える