0

I am writing a code in C++ to reverse all the words in a string without changing the order of the list

This is my code:

#include<bits/stdc++.h>
using namespace std;

int main()
{

string s = "God Ding";

int n = s.size();
    
int i = 0, j = 0;
    
while(j  < n){
    if(s[j] == ' ' || j == n-1){
        reverse(s.begin()+i, s.begin()+j);
        j++;
        i = j;
    }
    else{
        j++;
    }
}

cout << s;

return 0;

}

Expected Output: "doG gniD"

My output: doG Ding

2nd input: "Let's take LeetCode contest"

Expected Output: "s'teL ekat edoCteeL tsetnoc"

My Output: "s'teL ekat edoCteeL contest"

Everything is working fine but only the last word is not getting reversed

  • Separate each "word" into a vector of strings. Reverse each string in the vector. Output the strings in the vector in order. – Some programmer dude Feb 26 '22 at 16:20
  • 1
    @Someprogrammerdude yes I thought of that but I want to solve this problem using 2 pointer approach. I am not able to reverse the last word only –  Feb 26 '22 at 16:22
  • By the way, while `using namespace std;` is a [bad habit](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) it's commonly okay to use in small and simple examples, but you should [*never* include ``](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – Some programmer dude Feb 26 '22 at 16:31
  • Adding extra space to the string and removing it after the while loop solved my problem. Thanks, everyone! –  Feb 26 '22 at 16:38

4 Answers4

0

You need either to detect in your if the special situation of processing the last character, or add an extra reverse after the while, if the last word was not processed (i.e. the last char was not a space).

In your case, you've added the detection of last character, but did not process the reverse before the increment, as would be the case if the word ended with a space. To correct this situation, you must take into account this special situation:

if(s[j] == ' ' || j == n-1){
    reverse(s.begin()+i, s.begin()+j+(j==n-1?1:0));
    //                               ^ (if it's last, take +1)
    ...
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • That is why I have mentioned that if a space is encountered or j is at the last letter, reverse the word. Have I done something wrong in this case? –  Feb 26 '22 at 16:26
  • @coder25 yes, you detect it but before incrementing. I'll edit – Christophe Feb 26 '22 at 16:29
  • Added an extra space to the original string and the code is working now. Thanks a lot –  Feb 26 '22 at 16:34
  • @coder25 yes, this is a pragmatic alternative, that works well here. Keep in mind however, that sometimes we are not allowed to change the input (e.g. the input is `const`), which would require a copy of the string first, which could be a performance issue if performed on very large texts or on many strings ;-) – Christophe Feb 26 '22 at 16:38
0

I think this would be a better implementation for your code:

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    std::string s = "God Ding", reversed_string;

    std::string word;
    std::istringstream ss(s); // Declaring an in string stream

    while (std::getline(ss, word, ' ')) // Here getline gets every word in ss and stores it in the variable 'word'
    {
        // This loop reverses the variable 'word'
        for (int i = word.size() - 1; i >= 0; i--)
        {
            reversed_string.push_back(word[i]);
        }
        reversed_string.push_back(' ');
    }
    std::cout << reversed_string;

    return 0;
}

Also look up to why is "using namespace std" considered as a bad practice.

The Coding Fox
  • 1,488
  • 1
  • 4
  • 18
0

In order to reverse a word, you need i to index the first char, and j to index the char after the last one.

However, your loop exits whenever j indexes the char after the last one. That's why it never reverses the last word.

The simplest fix is to do one more check after the loop exits, and reverse the last word if there is one:

while(j < n) {
    if(s[j] == ' ') {  // remove the `j==n-1` test
        reverse(s.begin()+i, s.begin()+j);
        j++;
        i = j;
    } else {
        j++;
    }
}
if(i < j) {
    reverse(s.begin()+i, s.begin()+j);
}

The alternative would be to rewrite the loop in some way that finesses the problem. I don't really recommend this, given that you have something that almost works and that you know how to fix.

comingstorm
  • 25,557
  • 3
  • 43
  • 67
0

Here you have a working example:

#include <string>
#include <algorithm>
#include <iostream>

int main()
{
    std::string s = "God Ding";
    
    int i = 0;
    int j = 0;
    
    while (i <= s.length()) {
        if (i == s.length() || s[i] == ' ') {
            std::reverse(s.begin() + j, s.begin() + i);
            j = i + 1;
        }
        i++;
    }
    
    std::cout << s << std::endl;
    
    return 0;
}

I changed a lot of things. These are the issues you need to fix:

  1. Make your loop go beyond the last char.
  2. Reverse if j (from your code) is beyond the last char.
StackOverflower
  • 526
  • 3
  • 14