如何在C++中迭代句子中的单词?

4

我的输入是“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;
}

3
FYI,std::reverse函数实现了你的reverseword函数的功能 :P - Rakete1111
你可以运行一个循环直到找到空格,然后获取所有字符并将它们放入一个变量中,并进行反转。 - Sreeram TP
请参考 https://dev59.com/k3VC5IYBdhLWcg3wnCj6,了解分割字符串的最优雅方式。 - fundagain
你不需要拆分或连接任何东西。在原地反转每个单词。 - n. m.
2
你会如何处理输入的“Hello, world”?它应该是“,olleH dlroW”还是“olleH, dlroW”?如果有标点而没有空格,也是同样的情况。 - Christophe
显示剩余3条评论
7个回答

6

在对句子中的单词进行迭代之前,需要从输入中读取一句话。这行代码

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
@Rakete1111 对的,我只是不想假设 OP 不会从用户那里获取任何附加输入,所以我添加了一个 stringstream - Sergey Kalinichenko
好的解决方案。您如何处理空格、逗号等? - Chiel

1
   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<std::string>而不是栈分配的数组。 - Chiel
我猜这与我的评论有关。C++有容器可以避免像words[100]这样声明数组。这是不安全的,可能会导致分段错误。我建议你编辑一下,因为你的答案有一些不错的元素。 - Chiel

1
这里有一个解决方案,它使用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

0

0
上面的答案给出了一种将您的输入转换为单词的方法,即cin >> sentence返回一个“单词”(因此,只需重复调用它)。
然而,这引出了一个问题,即什么是“单词”。您想要将计算机构造 - 字符串 - 转换为更复杂的形式 - 单词。因此,必须定义您想要单词时意味着什么。它可以很简单,例如“空格”分隔的子字符串或您的字符串 - 然后使用split函数,或者一次读取一个单词(cin >> word
或者您可能有更严格的要求,例如不能包括标点符号(例如句子末尾的句点)或数字。然后考虑使用正则表达式和单词模式(例如,“\w+”)。
或者您可能想要像字典中找到的“真实”单词。然后需要考虑您的语言环境,将输入解析成块(使用split、Regex或其他方法),并在人类语言字典中查找每个块。
换句话说,“单词”解析仅取决于您的要求的简单程度或复杂程度。

这是一个很好的评论,但它并没有回答问题。 - n. m.
它建议使用 cin, split, regex 和字典查找。因此,它确实回答了问题,只是没有为 OP 提供程序。 - Les

0

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

-1

这个答案是我对抗全球变暖的谦虚贡献。

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

这假设“word”被定义为“一系列非空白字符”。可以很容易地用其他字符类替换“非空白”,例如,对于字母数字字符使用std::isalnum。一个反映自然语言科学中使用的词的现实概念的定义远远超出了本答案的范围。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接