C++ 颠倒句子中单词的顺序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17026740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:50:34  来源:igfitidea点击:

Reversing order of words in a sentence

c++arrays

提问by SpiderRico

#include <iostream>
#include <cstring>
using namespace std;
void reverse(char* sentence)
{
    int index = strlen(sentence) - 1;
    char last = '
Howdy Mr. Mcfly? 

Mcfly? Mr. Howdy
'; int hold = 0; while ( index != 0){ while (sentence[index] != ' ') index--; hold = index; //keeps the index of whitespace while (sentence[index] != last){ cout << sentence[index]; //printing till it either hits end character or whitespace. index++; } last = sentence[hold]; //Keeps the whitespace index = hold; // } } int main() { char* sentence = new char[256]; cin.getline(sentence, 256); reverse(sentence); }

I want to reverse the orders of words in a sentence and you can see my attempt above.

我想颠倒句子中单词的顺序,您可以在上面看到我的尝试。

Sample intput and output should be like this:

示例输入和输出应该是这样的:

Howdy Mr. Mcfly?
 Mcfly?

Where i get:

我在哪里得到:

void reverse(char* sentence)
{
    int index = strlen(sentence) - 1,hold,last = '
std::string sentence = "Your sentence which contains ten words, two of them numbers";
std::stringstream stream(sentence);
std::vector<std::string> words;
for ( std::string word; stream >> word; )
{
    words.push_back(word);
}
'; /*For the 1st iteration last is `
std::reverse(words.begin(), word.end());
` for all others it is ` `*/ while (index >= 0) { /* In your original code, This while loop(below) will continue to keep decrementing index even below `0`,You wont exit this while loop until you encounter a ` `. For the 1st word of the sentence you will never come out of the loop. Hence the check, index>=0 */ while (index>=0 && sentence[index] != ' ') index--; /* You can print the whitespace later*/ hold = index - 1; // This keeps track of the last character // of preceding word index++; //character after space while (sentence[index] != last) { cout << sentence[index]; index++; } last = ' '; index = hold; /* Dont print space after 1st word*/ if(index > 0) cout<<" "; } } int main() { char* sentence = new char[256]; cin.getline(sentence, 256); reverse(sentence); delete[] sentence; // Delete the allocated memory }

There are many similar questions around the internet but what i want is to find error in my own code.

互联网上有很多类似的问题,但我想要的是在我自己的代码中找到错误。

采纳答案by Suvarna Pattayil

As the other answers suggest you should use std::stringwhich can save lot of hassles. But just for the note,

正如其他答案所建议的那样,您应该使用std::string它可以节省很多麻烦。但只是为了笔记,

#include <string> // for storing strings in a C++ way
#include <sstream> // to easily separate sentences into words
#include <vector> // to dynamically store arbitrary amounts of words
#include <algorithm> // for std::reverse

Tryin to keep it as close to your logic

尽量让它接近你的逻辑

回答by stefan

You can use std::stringstd::vectorand std::reverseto make things easier:

您可以使用std::stringstd::vectorstd::reverse使事情变得更容易:

index = hold;

Now you have everything separated into words. You may now want to remove question marks or other punctuation, since the logic will be easier to implement while the words are still in the correct order. For reversing, do this:

现在你把所有的东西都分成了单词。您现在可能想要删除问号或其他标点符号,因为当单词仍处于正确顺序时,逻辑将更容易实现。要倒车,请执行以下操作:

void reverse(char* sentence, const int START)
{
    if(sentence[START] == '
#include <sstream>
#include <iostream>
#include <list>

int main() {
    char sentence[256];
    std::cin.getline(sentence, 256);

    std::istringstream f(sentence );

    std::string s;  
    std::list<std::string> strings;

    while (f >> s) 
    {
        strings.push_front(s);
    }
}
') return; char last = '
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace phx= boost::phoenix;
using namespace boost::spirit::qi;

int main()
{
    auto out = std::ostream_iterator<std::string>(std::cout, " ");

    boost::spirit::istream_iterator f(std::cin), l;
    std::cin.unsetf(std::ios::skipws);

    parse(f, l, 
            (
              (as_string [ +~char_("\n\t ") ] % +char_("\t ")) 
                    [ phx::reverse(_1), phx::copy(_1, phx::ref(out)) ]
            ) % eol [ phx::ref(std::cout) << "\n" ]
         );
}
'; int hold = 0; int index = START + 1; while(sentence[index] != '
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;

vector<string> split(char* str, char delimiter=' ')
{
        vector<string> result;
        do
        {
                char* begin =str;
                while(*str != delimiter && *str)
                        str++;
                result.push_back(string(begin, str));
        }while(0 != *str++);
        return result;
}
int main()
{
        string str;
        vector<string> tempStr;
        cout<<"Enter The String: ";
        getline(cin, str);
        cout<<endl;
        tempStr=split((char*)str.c_str());
        str.clear();
        cout<<"Final Reverse: \n";
        for(int i=tempStr.size()-1; i>=0; i--) str+=tempStr.at(i)+" ";
                //cout<<tempStr.at(i)<<" ";
        cout<<str<<endl;
        return 0;
}
' && sentence[index] != ' ') {//There are better ways to do this logic, but I wanted to remain true to your implementation as much as possible index++; } reverse(sentence, index); for(int j = START; j < index; j++) { cout << sentence[j]; } cout << endl; return; }

You'll need to include several headers:

您需要包含几个标题:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s,st,w;
    int i;
    getline(cin,s);
    istringstream is(s);
    st="";
    is>>st;
    while(is>>w)
    {
        st=w+' '+st;
    }
    cout<<st<<endl;
    return 0;

}

You can see this code in action with this demo on ideone.com

您可以在 ideone.com 上通过此演示查看此代码的运行情况

回答by ChrisCM

When you say

当你说

##代码##

You hav ean infinite loop. You're always going back to the point where you find your '\0' character I believe. What you should do is have two separate while loops. One to get you to the end of your character array, to find '\0'. And then another set of loops to return back to white space, then loop back forward printing out characters.

你有一个无限循环。我相信,您总是会回到找到 '\0' 字符的地方。您应该做的是有两个单独的 while 循环。一个让你到你的字符数组的末尾,找到'\0'。然后另一组循环返回空白,然后向前循环打印出字符。

NOTE: I like all the answers presented better, but this is why the code you posted is failing. Here is a version of this function that works with just cstrings.

注意:我更喜欢所有提供的答案,但这就是您发布的代码失败的原因。这是此函数的一个版本,仅适用于 cstring。

##代码##

I prints out a few extra end lines, you can of course format the output however you like, the hard part is done.

我打印出一些额外的结束行,您当然可以根据自己的喜好格式化输出,困难的部分已经完成。

回答by Enigma

##代码##

at this moment stringscontains the words in reverse order

此时strings包含倒序的单词

回答by sehe

Correction to the earlier version, firmly tongue-in-cheek:)

更正早期版本,坚决诙谐:)

Note that the program reads all of stdin, treating each individual line as a 'sentence'.

请注意,程序读取所有标准输入,将每一行视为“句子”。

##代码##

回答by Dustin Doosun Yang

I would like to use stack. 1.Tokenize the string using delimiter("") 2. push the word into the stack 3. As you pops up, store that word in the new string variable.

我想使用堆栈。1. 使用 delimiter("") 标记字符串 2. 将单词推入堆栈 3. 弹出时,将该单词存储在新的字符串变量中。

回答by Ambrish D

Here I used splitting (tokenizing) sentence into words and then use that for reverse printing. Hope this help-

在这里,我使用将句子拆分(标记化)成单词,然后将其用于反向打印。希望这有帮助-

##代码##

回答by Shawon

You can do it by istringstream class of C++

您可以通过 C++ 的 istringstream 类来完成

##代码##