如何以相反的顺序获取字符串以打印所有单词?

时间:2013-11-14 02:59:44

标签: c++ string loops

这是我目前正在尝试运行的代码片段:

int main()
{
    //Declare variables
    string userSentence = " ";
    string permanantUserSentence = " ";
    int spaceNumber = 0;
    int wordNumber = 0;
    int characterCount = 0;
    int reverseCount = 1;
    int posLastSpace = -1;
    int posSpace = 0;
    int reverseSpace = 0;
    int previousReverseSpace = 0;

    //Begin the loop
    while(userSentence != "quit" && userSentence != "q")
    {
        //Prompt the user for their sentence
        cout << "Enter command: ";
        getline(cin, userSentence);
        permanantUserSentence = userSentence;

        //Condition to make sure values are not calculated and printed for the quit conditions
        if(userSentence != "quit" && userSentence != "q")
        {

            //Find and print all of the words in reverse order
            cout << "\nIn Reverse Order: ";
            for(reverseCount = userSentence.length() - 1; reverseCount >= 0; reverseCount -= 1)
            {
                if(userSentence.substr(reverseCount, 1) == " ")
                {
                    cout << userSentence.substr(reverseCount, userSentence.length() - reverseCount);
                }
            }

            //Clear the input buffer and start a new line before the next iteration
            cout << endl;

这样做的目的是从名为userSentence的用户接收一个字符串,然后按照给出的相反顺序将每个单词打印给用户。例如,“注意!”会变成“出去!看”。运行此代码时,它不会为字符串的反转版本返回任何内容。

5 个答案:

答案 0 :(得分:0)

使用两个嵌套循环。 在第一个循环中声明一个缓冲区。 使用内部循环从后面读取输入字符串。 将读取的字符添加到缓冲区的前面。 如果读取的字符是空格,则打印缓冲区并重置它。

答案 1 :(得分:0)

尝试将每个单词放在堆栈上,并像这样打印出堆栈 “char * p = strtok(words,”“);”那里的东西是分裂词的东西, char * p称为迭代器,
这些单词将以相反的顺序打印出来     #包括     #包括     #include

using namespace std;

int main(void)
{
stack<string> mystack;
char words[] = "these are my words separated by spaces";
char *p = strtok(words, " ");
while( p )
{
    mystack.push(p);
    p = strtok(NULL, " ");
}

while( !mystack.empty() )
{
    cout << mystack.top() << " ";
    mystack.pop();
}
return 0;
}

答案 2 :(得分:0)

这可以撤销一句话:

#include <string>
#include <algorithm>
#include <sstream>

...

string sentenceYouHave;
istringstream stream(sentenceYouHave);

vector<string> words{istream_iterator<string>{stream},
                     istream_iterator<string>{});

reverse(words.begin(), words.end());

如果您想要计算任何内容,您还可以使用accumulate countcount_if标准算法。

通过提升,这里有一个更优雅的解决方案:

#include <algorithm>
#include <iostream>
#include <string>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/regex.hpp>

using namespace std;
namespace b = boost;
namespace ba = boost::adaptors;

using string_range = boost::iterator_range<std::string::const_iterator>;


struct submatch_to_string_range {
    typedef string_range result_type;

    template <class T>
    string_range operator()(T const & s) const {
        return string_range(s.first, s.second);
    }
};


int main(int argc, char * argv[]) {
    string sentence = "This is a sentence";
    auto words_aux =
    sentence |
    ba::tokenized(R"((\w+))") |
    ba::transformed(submatch_to_string_range{});

    vector<string_range> words(words_aux.begin(), words_aux.end());
    boost::reverse(words);
    for (auto const & word : words) {
        cout << word << endl;
    }
}

答案 3 :(得分:0)

这样的事情:

#include <iostream>
#include <vector>
#include <functional>
#include <iterator>

// using own split
namespace bs {
    template< typename Container >
        void split( Container & c
                  , std::string const & line
                  , const std::string & del ) {
            std::string::size_type b( 0 );
            std::string::size_type pos( b );

            while ( pos < line.size() ) {
                pos = line.find_first_of( del, b );
                if ( pos != b ) {
                    c.push_back( line.substr( b, pos - b) );
                }
                b = pos + 1;
            }
        }
}

void reverse( std::string & line )
{
   using vec = std::vector< std::string >;
   vec v;

   bs::split( v, line, std::string( " ,." ) );
   v.erase( std::remove_if(
       v.begin()
       , v.end()
       , [&]( std::string & s ) {
            //bs::trim( s ); // trim if needed
            return s.empty();
      } )
      , v.end() );

   for ( vec::reverse_iterator it( v.rbegin() ), end( v.rend() );
         it != end; ++it ) std::cout << *it << " ";
   std::cout << std::endl;
}


int main() {
    std::string s( "some string   to, reverse" );
    reverse( s );
    std::string s2( "nothingtosplit" );
    reverse( s2 );
}

输出:

reverse to string some 
nothingtosplit

答案 4 :(得分:0)

以下是有问题的代码:

if(userSentence.substr(reverseCount, 1) == " ")
{
  cout << userSentence.substr(reverseCount, userSentence.length() - reverseCount);
}

每次找到“”时,您都会将位置reverseCount的字符输出到字符串末尾!

例如,如果输入的字符串是“请注意!”,首先你会得到“请!”,接下来你会“请出去!”不是“出去”。

因为在字符串的开头不是“”,你永远不会输出第一个单词。

所以,我认为我们可以修改这种形式的代码,并且效果很好:

cout << "In Reverse Order: ";
size_t length = userSentence.length();
for(reverseCount = length - 1; reverseCount >= 0; reverseCount -= 1) {
  if(userSentence.substr(reverseCount, 1) == " ") {
    cout << userSentence.substr(reverseCount + 1, length - reverseCount) << " ";
    length = reverseCount - 1;
  }
}
// output the first words.
cout << userSentence.substr(reverseCount + 1, length - reverseCount) << "\n";
cout << endl;

希望这会对你有所帮助。