Lucas
Lucas

Reputation: 1617

Reversing words of a sentence?

I do not understand what I am doing wrong. It looks like this should work:

Calling reverse_reverse("this house is blue"); should first print out "this house is blue", then "blue is house this"..

void reverse_reverse(char * str) {
    char temp;

    size_t len = strlen(str) - 1;
    size_t i;
    size_t k = len;

    for(i = 0; i < len; i++) {
        temp = str[k];
        str[k] = str[i];
        str[i] = temp;
        k--;

        if(k == (len / 2)) {
            break;
        }
    }

    cout << str << endl;

    i = 0;
    for(k = 0; k < len; k++) {
        if(str[k] == ' ') {
            size_t a = k;
            for(size_t b = i; b < k; b++) {
                temp = str[b];
                str[b] = str[a];
                str[a] = temp;
                a--;

                if(a == (((k - i) / 2) + i)) {
                    break;
                }
            }
        }
        i = k + 1;
    }

    cout << str << endl;
}

Upvotes: 0

Views: 2598

Answers (3)

Peyman
Peyman

Reputation: 447

Instead of reversing the whole string once and then each word another time, you could do something like this:

void reverse(const char *s)
{
    int e = strlen(s) - 1;
    int b = e;
    while (b) {
        while (b && s[b - 1] != ' ') 
            b--;
        int i;
        for (i = b; i <= e; ++i)
            putchar(s[i]);
        while (b && s[b - 1] == ' ') {
            printf(" ");
            b--;
        }
        e = b - 1;
    }
}

Upvotes: 0

Jim Balter
Jim Balter

Reputation: 16406

It would be easier to read and understand and debug your code if it were simpler. Note that you repeat code to reverse a sequence of characters in two different places -- you should use a subroutine. A simpler, more intuitive, and faster algorithm than the one you're using is

/* reverse s[first ... last] in place */
void reverse(char* s, int first, int last){
    for( ; first < last; first++, last-- ){
        char c = s[first];
        s[first] = s[last];
        s[last] = c;
    }
}

Then your program reduces to something simple:

void reverse_reverse(char* s) {
    int len = strlen(s);
    reverse(s, 0, len - 1);

    for( int word = 0, i = 0;; i++ ){
        if( i == len || s[i] == ' ' ){
            reverse(s, word, i-1);
            if( i == len ) break;
            word = i + 1;
        }
    }
}

Note that I moved the end test inside of the for loop to handle the last word in the string if it isn't followed by a space.

Upvotes: 1

Aryabhatta
Aryabhatta

Reputation:

You have

i = k+1

and then the for loop

for(size_t b = i; b < k; b++)

This will never go in as i > k before the start of the loop and thus b > k.

Perhaps you meant to have that line in the if block:

if (str[k] == ' ') {  
...

    i = k+1; // <----- Here
}
// i = k+1; // Instead of here.

I don't think that will work either, but will get you much closer to what you desire.

Upvotes: 5

Related Questions