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

文中の単語の順序を逆にしたいのですが、上の私の試みを見ることができます。

サンプルの入力と出力は次のようになります。

Howdy Mr. Mcfly? 

Mcfly? Mr. Howdy

私が得る場所:

Howdy Mr. Mcfly?
 Mcfly?

インターネット上には同様の質問がたくさんありますが、私が欲しいのは自分のコードでエラーを見つけることです。

4

8 に答える 8

12

とを使用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のこのデモで、このコードの動作を確認できます。

于 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' の文字を見つけたところにいつも戻っていると思います。あなたがすべきことは、2 つの別々の 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

以前のバージョンへの修正、しっかりと冗談:)

プログラムは stdin のすべてを読み取り、個々の行を「文」として扱うことに注意してください。

#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

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 に答える