2013-06-10 21 views
5
#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); 
} 

Chcę odwrócić kolejność słów w zdaniu i możesz zobaczyć moją próbę powyżej.Kolejność odwrotna słów w zdaniu

intput próbki i wyjście powinno być tak:

Howdy Mr. Mcfly? 

Mcfly? Mr. Howdy 

gdzie mogę dostać:

Howdy Mr. Mcfly? 
Mcfly? 

Istnieje wiele podobnych pytań całym internecie, ale to, co chcę jest, aby znaleźć błąd w moim własnym kod.

+6

Jeśli używasz C++, dlaczego używasz char *? Byłoby to znacznie łatwiejsze w przypadku ciągów. Zauważyłem, że oznaczono Cię tagiem "dynamiczne tablice", czy istnieje jakiś szczególny powód, dla którego używasz char *, które spowodowałoby, że odpowiedź, która byłaby niedopuszczalna za pomocą ciągów? – ChrisCM

+1

co widzisz po uruchomieniu przykładu za pomocą debuggera? – TooTone

+1

Teraz byłby dobry moment, aby rozpocząć naukę korzystania z debuggera. Przechodząc przez kod i sprawdzając zmienne, powinieneś być w stanie szybko znaleźć błędy. –

Odpowiedz

3

Jak inne odpowiedzi sugerują powinieneś użyć std::string, który może zaoszczędzić wiele kłopotów. Ale tylko dla notatki,

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 
} 

Próbując utrzymać go jak najbliżej swojej logiki

+0

Właśnie tego chciałem, tak bardzo. – SpiderRico

10

Można użyć std::stringstd::vector i std::reverse aby ułatwić:

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

Teraz masz wszystko podzielone na słowach. Możesz teraz usunąć znaki zapytania lub inne znaki interpunkcyjne, ponieważ logika będzie łatwiejsza do zrealizowania, a słowa będą nadal w poprawnej kolejności. Dla odwrócenia, to zrobić:

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

Musisz zawierać kilka nagłówków:

#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 

widać ten kod w akcji z tego demo on ideone.com

+0

/* Nie drukuj miejsca po pierwszym słowie */
if (index> 0)
Jeśli zdanie zaczyna się od pojedynczej litery, w powyższej kontroli nie zostanie wydrukowane miejsce.
Powinno być, jeśli (indeks> = 0) –

+0

@inquisitive_mind Przepraszam? Nie mam czegoś takiego w mojej odpowiedzi/kodzie. Czy możesz wyjaśnić mi, co twój komentarz powinien mi powiedzieć? – stefan

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

w tej chwili strings zawiera słowa w odwrotnej kolejności

+0

hmm .. Zgadzam się z tym jednym – Enigma

0

Korekta do wcześniejszych rsion, mocno zaciśnięty język :)

Zauważ, że program odczytuje wszystkie standardowe wejścia, traktując poszczególne wiersze jako "zdanie".

#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" ] 
     ); 
} 
+0

to odwraca cały znak zdanie po znaku, a nie słowo po słowie. – stefan

+0

ah, masz rację :) no cóż, używając Boost Range naprawiłbym to i sprawię, że będzie bardziej elegancki, ale myślę, że ten rodzaj przekracza zakres użytecznych odpowiedzi ... – sehe

+0

cóż, ja osobiście nie jestem fanem boost, ale inni mogą się nie zgodzić. Zobaczmy Twoje podejście doładowania ;-) – stefan

1

Kiedy mówisz

index = hold; 

hav sprzątać nieskończoną pętlę. Zawsze powracasz do punktu, w którym wierzysz w swoją postać "0". Powinieneś mieć dwie oddzielne pętle while. Jeden, który doprowadzi cię do końca twojej tablicy postaci, aby znaleźć "\ 0". A następnie kolejny zestaw pętli, aby powrócić do białej przestrzeni, a następnie wróć do przodu, drukując znaki.

UWAGA: Podobają mi się wszystkie przedstawione odpowiedzi lepiej, ale dlatego kod, który wysłałeś, zawodzi. Oto wersja tej funkcji, która działa po prostu 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; 
} 

Wydrukowałem kilka dodatkowych linii końcowych, można oczywiście sformatować wyjście, jak chcesz, twarda część jest zrobiona.

0

Chciałbym użyć stosu. 1. Przetwórz ciąg znaków za pomocą ogranicznika ("") 2. wciśnij słowo do stosu 3. Po wyskoczeniu przechowuj to słowo w nowej zmiennej łańcuchowej.

0

Tutaj użyłem zdania dzielącego (tokenizującego) na słowa, a następnie używam go do druku odwróconego. Nadzieję, że to Pomoc-

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

Można to zrobić przez klasy 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; 

} 
Powiązane problemy