1

I have just started learning C++. I am writing a program to reverse the order of words in a string. If there is a sentence,"I love New York!". It should be changed to, "!York New love I".

I am using the algorithm which has two simple steps.

  1. Reverse the string.
  2. Reverse the letters of words.

For example, for above string, i will first convert it to, "!kroY weN evol I" and then i will change letters of words like "!kroY" to "York!".

Now the problem is that how would i know that from where the word starts and where it ends. This is what i have done so far. But this program is not working as intended. I am unable to identify the word and then reverse it.

#include <iostream>
#include <string>

std::string reverseText(std::string x){
std::string y;
for(int i=x.size()-1;i>=0;i--) y += x[i];
return y;
}

std::string reverseWords(std::string x){

std::string y = reverseText(x);
bool wordFound = true;
std::string temp1,ans;

for(size_t i=0;i<y.size();i++){


    if(wordFound){ 

        if(y[i]!=' ') temp1+=y[i];  // if there is a letter, store that in temp1.

        else if(y[i]==' ')   // if there is a space, that means word has ended.
        {
            ans += reverseText(temp1);  // store that word, in ans.
            temp1=" ";                  
            wordFound=false;}
        }

    if(y[i]==' ' && y[i+1]!=' ') wordFound=true;
    }
return ans;
}

int main(){
std::cout<<reverseWords("My name is Michael");
}

Output : Michaelis name

user3834119
  • 411
  • 9
  • 21
  • What doesn't work? What happens when you run it? – Theolodis Jul 20 '14 at 12:06
  • @Theolodis Output is not correct, my logic is not right. i guess. – user3834119 Jul 20 '14 at 12:08
  • Well, it would be nice to add the output you get into the question ;) – Theolodis Jul 20 '14 at 12:08
  • You might scan for spaces and push words on a stack. –  Jul 20 '14 at 12:12
  • also http://stackoverflow.com/questions/1009160/reverse-the-ordering-of-words-in-a-string?rq=1 – quantdev Jul 20 '14 at 12:12
  • wouldn't it be simple to split the strings by space and add it to a stack and then populate another string by emptying the stack? – Vivek V K Jul 20 '14 at 12:16
  • You are doing it wrong. The problem is intended to be solved in-place, without creating any additional strings. In this setting the solution of reversing the string, then reversing each individual word is *very* smart. If you create an additional string, not speaking of *many* additional strings, it becomes... somewhat less than stellar. – n. m. could be an AI Jul 20 '14 at 12:18
  • @n.m. I know i am doing it wrong. That's why i posted. If you can provide a solution, that would be great. – user3834119 Jul 20 '14 at 12:21
  • 2
    The question is now closed as a duplicate, but all answers in the other question are bad. [Here](http://ideone.com/9W5lJr) is mine. – n. m. could be an AI Jul 20 '14 at 14:06
  • @n.m. Your program works fine. But when i enter something like,"New york." It returns, "york. New" Whereas it should return, ".york New" – user3834119 Jul 20 '14 at 15:08
  • I don't know what the authoritative definition of word is. (I hear most linguists don't, either). I have arbitrarily used "a sequence of graphic characters". I could have used "a sequence of (something else)". It makes no difference as far as the technique being illustrated is concerned. It is very easy to modify the program so it will recognize words as sequences of letters, or of whatever class of characters you want. With your permission I will leave it as an exercise for you. – n. m. could be an AI Jul 20 '14 at 15:27

1 Answers1

1

I have not tested this extensively and there still might be problems with it, but it produced the correct output for the case you gave. I tried to fix your code without changing it too much.

#include <iostream>
#include <string>

std::string reverseText(std::string x){
    std::string y;
    for(int i=x.size()-1;i>=0;i--) y += x[i];
    return y;
}

std::string reverseWords(std::string x) {
    std::string y = reverseText(x);
    bool wordFound = true;
    std::string temp1 = " ", ans;

    for(size_t i = 0; i < y.size(); i++) {
        if(wordFound){
            if(y[i] != ' '){
                temp1 += y[i];  // if there is a letter, store that in temp1.
            } else if(y[i]==' ') {  // if there is a space, that means word has ended.
                ans += reverseText(temp1);  // store that word, in ans.
                temp1 = " ";
                wordFound=false;
            }
        }
        if(y[i]==' ' && y[i+1]!=' ') wordFound=true;
    }
    ans += reverseText(temp1);
    return ans;
}

int main(){
    std::cout<<reverseWords("My name is Michael");
}

Summary of changes

You forgot to initialize the first string with a space

std::string temp1 = " ", ans;

After looping over y you forgot to "flush" the contents of temp1 into answer

ans += reverseText(temp1);
Moyamo
  • 358
  • 2
  • 10
  • Thanks. It is working for that case. But if user writes, "I love New York!". It returns, "York! new love I". But as i mentioned in the question, it should be,"!York new love I". Can you suggest a way to fix this? – user3834119 Jul 20 '14 at 12:30
  • @user3834119: you need to change the way you define words. In your code, you have defined it as "string of characters separated by space", and `!` and `York` are not separated by spaces thus are treated as a single word. – Matthieu M. Jul 20 '14 at 12:32
  • @MatthieuM. You are right. But i couldn't figure out a way to define words other than this(spaces). – user3834119 Jul 20 '14 at 12:35
  • 1
    @user3834119: Well, the simplest solution is to use a set. It can be either a set of "word-composing" characters or a set of "word-boundaries" characters. For example, supposing that you are only dealing with ASCII strings, you could say that word-composing characters are `[A-Za-z-']` and anything else is a word-boundary. Then if you look at the [second answer](http://stackoverflow.com/a/1009331/147192) of the canonical question, you need just replace the test `in_text[rindex] == ' '` by `is_word_boundary(in_text[rindex])`. – Matthieu M. Jul 20 '14 at 12:58