6
#include <iostream>
#include <cstring>
using namespace std;
void reverse(char* sentence)
{
    int index = strlen(sentence) - 1;
    char last = '\0';
    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? Mr. Howdy

Where i get:

Howdy Mr. Mcfly?
 Mcfly?

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

4

8 回答 8

12

您可以使用std::string std::vectorandstd::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 上通过此演示查看此代码的运行情况

于 2013-06-10T15:05:11.290 回答
4

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

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

尽量让它接近你的逻辑

于 2013-06-11T08:49:18.400 回答
1
#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包含相反顺序的单词

于 2013-06-10T15:08:42.210 回答
1

当你说

index = hold;

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

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

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


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

我打印了一些额外的结束行,你当然可以随意格式化输出,困难的部分已经完成。

于 2013-06-10T15:26:48.213 回答
0

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

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

#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" ]
         );
}
于 2013-06-10T15:23:22.967 回答
0

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

于 2015-05-06T01:39:33.730 回答
0

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

#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;
}
于 2015-06-24T05:23:17.657 回答
0

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

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

}
于 2016-06-21T20:23:09.850 回答