简体   繁体   中英

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

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM