翻译句子中单词的顺序

时间:2013-06-10 14:51:58

标签: c++ arrays

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

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

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

Howdy Mr. Mcfly? 

Mcfly? Mr. Howdy

我得到的地方:

Howdy Mr. Mcfly?
 Mcfly?

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

8 个答案:

答案 0 :(得分:11)

您可以使用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

您可以使用此demo on ideone.com

查看此代码

答案 1 :(得分: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
}

尝试使其尽可能接近逻辑

答案 2 :(得分: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包含相反顺序的单词

答案 3 :(得分: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;
}

我打印出一些额外的结束行,你当然可以根据自己的喜好格式化输出,但很难完成。

答案 4 :(得分: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" ]
         );
}

答案 5 :(得分:0)

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

答案 6 :(得分: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;
}

答案 7 :(得分: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;

}