【问题标题】:How can I get a string to print all of its words in the reverse order?我怎样才能得到一个字符串以相反的顺序打印它的所有单词?
【发布时间】:2013-11-14 02:59:43
【问题描述】:

这是我当前尝试运行的代码的 sn-p:

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 的字符串,然后以与给出的相反顺序将每个单词打印给用户。例如,“小心!”会变成“out!看”。运行此代码时,它不会为字符串的反转版本返回任何内容。

【问题讨论】:

  • 这是 StackOverflow 上一个非常流行的问题,用许多不同的编程语言提出。你为什么不四处看看?
  • 从这个问题右侧的相关问题列表开始。 --------->>>>>>>>>> 你也可以考虑使用调试器来单步调试代码并找出什么不工作以及为什么。
  • 这不完全一样。不过看看stackoverflow.com/questions/17026740/…

标签: c++ string loops


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    尝试将每个单词放在一个堆栈上,然后像这样打印出堆栈 "char *p = strtok(单词, " ");" " " 里面的东西就是分割词的东西, char *p 称为迭代器,
    并且单词将以相反的顺序打印出来 #包括 #包括 #包括

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

    【讨论】:

      【解决方案3】:

      类似这样的:

      #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】:

        这可以反转一个句子:

        #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 标准算法。

        有了 boost,这里有一个更优雅的解决方案:

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

        【讨论】:

          【解决方案5】:

          这是有问题的代码:

          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;
          

          希望这对你有帮助。

          【讨论】:

            猜你喜欢
            • 2018-05-17
            • 1970-01-01
            • 2021-12-21
            • 1970-01-01
            • 2016-10-16
            • 2021-12-14
            • 1970-01-01
            • 2012-02-03
            • 1970-01-01
            相关资源
            最近更新 更多