【问题标题】:How to iterate over the words of a sentence in C++?如何在 C++ 中迭代一个句子的单词?
【发布时间】:2023-03-13 21:30:02
【问题描述】:

我的输入是“Hello World”,目标输出是“olleH dlroW”。

所以我的想法是把句子变成一个变量,然后循环遍历句子中的单词,将每个单词反转,最后将它们连接成一个新变量。

我的问题是:如何迭代句子的单词?

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

string reverseword(string word)
{
    string rword;
    int size = word.length();
    while (size >= 0)
    {
        rword+= word[size];
        size = size -1;
    }   
    return rword;
}

int main()
{ 
    string sentence;
    cout<<"Enter the word/sentence to be reversed: ";
    cin >> sentence;
    string rsentence;
    // for every word in the sentence do
    {
        rword = reverseword(word);
        rsentence = rsentence + " " + rword; 
    }
    cout<<rword;
    return 0;
}

【问题讨论】:

  • 仅供参考 std::reverse 做你的 reverseword 函数所做的事情:P
  • 你可以运行一个top直到你找到空间并抓取所有字符并将它们放入一个变量并执行反向操作
  • 您不需要拆分或连接任何内容。就地反转每个单词。
  • 您将如何处理输入“Hello, world”?它应该导致 ",olleH dlroW" 还是 "olleH, dlroW" ?如果有标点符号且没有空格,则相同

标签: c++ string loops


【解决方案1】:

在您可以迭代句子中的单词之前,您需要从输入中读取一个句子。这一行

cin >> sentence;

阅读句子的第一个单词,而不是整个句子。请改用getline

std::getline(std::cin, sentence);

使用内存中的sentence,您可以使用istream_iterator 逐字迭代它,如下所示:

stringstream ss(sentence);
for (auto w = istream_iterator<string>(ss) ; w != istream_iterator<string>() ; w++) {
    string &word = *w;
    ...
}

Demo.

【讨论】:

  • 根据输入的不同,不需要stringstream,直接使用std::cin即可。
  • @Rakete1111 是的,我只是不想假设 OP 不会接受用户的任何额外输入,所以我添加了 stringstream
  • 不错的解决方案。如何处理空格、逗号等?
【解决方案2】:

这里有一个使用findreverse实现输出的解决方案:

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


int main() {
    std::string sentence;
    std::getline(std::cin, sentence);
    std::cout << sentence << std::endl;
    size_t cpos = 0;
    size_t npos = 0;
    while((npos = sentence.find(' ', cpos)) != std::string::npos)
    {
        std::reverse(sentence.begin() + cpos, sentence.begin() + npos);
        cpos = npos + 1;
    }
    std::reverse(sentence.begin() + cpos, sentence.end());
    std::cout << sentence << std::endl;
    return 0;
}

输入:

this is a nice day

输出:

this is a nice day
siht si a ecin yad

【讨论】:

    【解决方案3】:
       for(short i=0;i<sentence.length();i++){
    
            if(sentence[i] == ' '){
                counter++;
                i++;
            }
    
            words[counter] += sentence[i];
        }
    

    注意上面的循环用空格分割句子并存储到一个字符串数组,words[]

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    
    using namespace std;
    
    string reverseword(string word) // function to reverse a word
    {
        string rword;
        int size = word.length();
        while (size >= 0)
        {
            rword+= word[size];
            size = size -1;
        }   
        return rword;
    }
    
    int main()
    { 
        string sentence;
    
        cout << "Enter the word/sentence to be reversed: ";
        std::getline(std::cin, sentence);
    
    
        string rsentence;
        string words[100];
    
    
        string rword;
    
        short counter = 0;
    
        for(short i=0; i<sentence.length(); i++){ // looping till ' ' and adding each word to string array words
    
            if(sentence[i] == ' '){
                counter++;
                i++;
            }
    
            words[counter] += sentence[i];
        }
    
    
    
        for(int i = 0; i <= counter; i++) // calling reverse function for each words
        {
            rword = reverseword(words[i]);
    
            rsentence = rsentence + " " + rword;  // concatenating reversed words
        }
    
        cout << rsentence; // show reversed word
    
        return 0;
    }
    

    我已经更正了代码。希望这会有所帮助...!!

    注意:您使用 cin 来读取不可能的空格分隔字符串。您必须使用std::getline(std::cin, sentence) 来读取空格分隔的字符串。

    你也可以使用std::reverse()来反转一个字符串

    【讨论】:

    • 请使用std::vector&lt;std::string&gt; 而不是堆栈分配的数组。
    • 我想这与我的评论有关。 C++ 有容器可以让你避免像words[100] 这样的数组声明。这是不安全的,可能会导致分段错误。我建议你编辑它,因为你的答案有一些不错的元素。
    【解决方案4】:

    请参考Most elegant way to split a string? 把你的句子分成标记(单词) 然后,遍历新的单词列表以执行任何操作

    【讨论】:

      【解决方案5】:

      上面的答案提供了一种将您的输入转换为单词的方法,即cin &gt;&gt; sentence 返回一个“单词”(因此,只需重复调用它)。

      然而,这就引出了什么是“词”的问题。您想将计算机构造 - 字符串 - 翻译成更复杂的形式 - 单词。所以,当你想要单词时,你必须定义你的意思。它可以像“空格”分隔的子字符串或您的字符串一样简单 - 然后使用 split 函数,或一次读取您的字符串一个单词 (cin &gt;&gt; word)

      或者您可能有更严格的要求,例如不能包含标点符号(例如句末的句号)或数字。然后考虑使用正则表达式和单词模式(例如,“\w+”)。

      或者您可能想要在字典中找到的“真实”单词。然后你需要考虑你的语言环境,将你的输入解析成块(使用 split、Regex 或其他东西),并在人类语言字典中查找每个块。

      换句话说,“单词”解析只取决于您的要求是简单还是复杂。

      【讨论】:

      • 这是一个很好的评论,但它没有回答问题。
      • 它建议使用cinsplitregex 和字典查找。所以它确实回答了这个问题,只是没有为 OP 提供程序。
      【解决方案6】:

      借助 Boost,您可以使用 boost::split 函数:

      #include <iostream>
      #include <vector>
      #include <string>
      #include <algorithm>
      #include <boost/algorithm/string.hpp>
      
      int main()
      {
          std::string sentence = "Hello world";
      
          std::vector<std::string> words;
          boost::split(words, sentence, boost::is_any_of(" "));
      
          std::string rsentence;
          for (std::string word : words) // Iterate by value to keep the original data.
          {
              std::reverse(word.begin(), word.end());
              rsentence += word + " "; // Add the separator again.
          }
          boost::trim(rsentence); // Remove the last space.
      
          std::cout << rsentence << std::endl;
      
          return 0;
      }
      

      【讨论】:

        【解决方案7】:

        这个答案是我为对抗全球变暖所做的微薄贡献。

        #include <string>                                                            
        #include <iostream>                                                          
        #include <algorithm>                                                         
        #include <cctype>                                                            
        
        int main()                                                                   
        {                                                                            
            std::string sentence;                                                    
            while (std::getline(std::cin, sentence))                                 
            {                                                                        
                auto ws = sentence.begin();                                          
        
                while (ws != sentence.end())                                         
                {                                                                    
                    while (std::isspace(*ws)) ++ws;                                  
                    auto we = ws;                                                    
                    while (we != sentence.end() && !std::isspace(*we)) ++we;         
                    std::reverse(ws, we);                                            
                    ws = we;                                                         
                }                                                                    
                std::cout << sentence << "\n";                                       
            }                                                                        
        }
        

        这假设“单词”被定义为“一系列非空白字符”。替换不同的字符类而不是“非空白”很容易,例如对于字母数字字符,请使用 std::isalnum。反映现实世界中单词概念的定义,例如在自然语言科学中使用的远远超出了这个答案的范围。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-12-11
          • 2011-01-26
          • 2023-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-29
          相关资源
          最近更新 更多