Monday, September 19, 2011

Reverse the words in a sentence in place

Problem

Given a sentence you have to reverse it word by word.

Example
That is, given a sentence like this :
I am a good boy

The in place reverse would be:
boy good a am I

Solutions

Method1 - Reverse the sentence first and then words again
First reverse the whole string and then individually reverse the words
I am a good boy
<------------->
yob doog a ma I
<-> <--> <-> <-> <->
boy good a am I
Here is some C code to do the same ....
/*
Algorithm..
1. Reverse whole sentence first.
2. Reverse each word individually.
All the reversing happens in-place.
*/

void reverseWords( char * str )
{
    int i = 0, j = 0;
    reverseString( str, strlen(str) ); // yob doog a ma I

// Found a word or reached the end of sentence
    while( 1 ) // Loop forever
    {
        if( *(str+j) == ' ' || *(str+j) == '\0') 
        {
            reverseString( str+i, j-i );
            i = j+1;
        }
        if( *(str+j) == '\0')
        {
            break;
        }
        j++;
    }
}

void reverseString(char* str, int len)
{
    int i, j;
    char temp;
    i=j=temp=0;

    j=len-1;
    for (i=0; i<j; i++, j--)
    {
        temp=str[i];
        str[i]=str[j];
        str[j]=temp;
    }
}

Method2
Another way to do it is, allocate as much memory as the input for the final output. Start from the right of the string and copy the words one by one to the output.
Input : I am a good boy
< --
< -------
< ---------
< ------------
< --------------
Output : boy
: boy good
: boy good a
: boy good a am
: boy good a am I
The only problem to this solution is the extra space required for the output and one has to write this code really well as we are traversing the string in the reverse direction and there is no null at the start of the string to know we have reached the start of the string!. One can use the strtok() function to breakup the string into multiple words and rearrange them in the reverse order later.

Method3

Create a linked list like
| I | -> | < spaces > | -> | am | -> | < spaces > | -> | a | -> | < spaces > | -> | good | -> | < spaces > | -> | boy | -> | NULL |
Now its a simple question of reversing the linked list!. There are plenty of algorithms to reverse a linked list easily. This also keeps track of the number of spaces between the words. Note that the linked list algorithm, though inefficient, handles multiple spaces between the words really well.

0 comments:

Post a Comment