反转句子中单词的顺序

Reversing order of words in a sentence

本文关键字:顺序 单词 句子      更新时间:2023-10-16
#include <iostream>
#include <cstring>
using namespace std;
void reverse(char* sentence)
{
    int index = strlen(sentence) - 1;
    char last = '';
    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);
}

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

示例输入和输出应如下所示:

Howdy Mr. Mcfly? 
Mcfly? Mr. Howdy

我在哪里得到:

Howdy Mr. Mcfly?
 Mcfly?

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

您可以使用

std::string std::vectorstd::reverse使事情变得更容易:

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

现在你把所有东西都分成了文字。您现在可能希望删除问号或其他标点符号,因为当单词仍按正确顺序排列时,逻辑将更容易实现。要反转,请执行以下操作:

std::reverse(words.begin(), word.end());

您需要包含多个标头:

#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

您可以在此演示中看到此代码的实际效果 ideone.com

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

void reverse(char* sentence)
{
    int index = strlen(sentence) - 1,hold,last = '';
    /*For the 1st iteration last is `` 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
}

尝试使其尽可能接近您的逻辑

当你说

index = hold;

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

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

void reverse(char* sentence, const int START)
{
    if(sentence[START] == '') return;
    char last = '';
    int hold = 0;
    int index = START + 1;

    while(sentence[index] != '' && 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;
}

我打印出一些额外的结束行,您当然可以随心所欲地格式化输出,困难的部分已经完成。

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

此时strings以相反的顺序包含单词

对早期版本的更正,坚定地开玩笑:)

请注意,程序读取所有标准,将每一行都视为一个"句子"。

#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_("nt ") ] % +char_("t ")) 
                    [ phx::reverse(_1), phx::copy(_1, phx::ref(out)) ]
            ) % eol [ phx::ref(std::cout) << "n" ]
         );
}

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

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

#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;
}
你可以

通过 istringstream 类来做到这一点C++

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