user6652930
user6652930

Reputation:

How can I reverse each word in a string?

I'm constrained to not use anything from <string.h>.

I want to reverse each word in the passed string.

This is what I have so far:

#include <stdio.h>

char * reversepPrint( char *name )
{
    char *normal = name, *reverse = name;

    while ( *reverse ) ++reverse;

    if ( normal < reverse )
    {
        for ( ; normal < --reverse; ++normal  )
        {
            char c = *normal;
            *normal = *reverse;
            *reverse  = c;
        }
    }

    return name;
}

int main( void ) 
{
    char s[] = "Simon liebt Pizza!";

    printf("%s", reversepPrint(s));

    return 0;
}

My code is reversing the whole string, but I want individual words to be reversed - so the result for this example would be "nomiS tbeil !azziP".

Upvotes: 1

Views: 1364

Answers (6)

Ian Abbott
Ian Abbott

Reputation: 17403

Here is a version using some nested loops:

#include <ctype.h>

char * reversepPrint( char *name )
{
    char *s = name;

    while (*s)
    {
        char *t = s;

        /* Find end of non-space character sequence. */
        while (*t && *t == (unsigned char)*t && !isspace(*t))
        {
            t++;
        }
        if (t - s > 1)
        {
            /* Got a non-space character sequence of length > 1. */
            char *e = t;

            /* Reverse the non-space character sequence. */
            do
            {
                char tmp = *s;

                *s++ = *--e;
                *e = tmp;
            } while (s < e);

            /* Start past non-space characters for next iteration. */
            s = t;
        }
        else
        {
            /* Skip space or singleton non-space. */
            s++;
        }
    }

    return name;
}

The variable s is used to advance through the name string in each iteration of the outer while loop. The variable t is initialized to s in each iteration of the outer loop and is then advanced past any non-space characters by the inner while (*t && ...) loop. After advancing t past the any non-space characters, the length of the sequence of non-space characters is t - s. (If *s is a space character then this length will be 0.) If this length is greater than 1, it uses the inner do { ... } while loop to reverse the sequence of non-space characters, and then assigns s = t ready for the next iteration of the outer loop. Otherwise, *s is either a space character or a singleton non-space character, so s is advanced by one character for the next iteration of the outer loop.

Upvotes: 0

nani
nani

Reputation: 1

try this logic instead,reverse the individual words of string one by one, for example if the string is "i like programming" after reversing the individual words the string should be "i ekil gnimmargorp".

i hope this code snippet helps

void reverse(char* begin, char* end) 
{ 
    char temp; 
    while (begin < end) { 
        temp = *begin; 
        *begin++ = *end; 
        *end-- = temp; 
    } 
} 

// Function to reverse words 
void reverseWords(char* s) 
{ 
    char* begin = s; 

    char* temp = s;  
    while (*temp) { 
        temp++; 
        if (*temp == '\0') { 
            reverse(begin, temp - 1); 
        } 
        else if (*temp == ' ') { 
            reverse(begin, temp - 1); 
            begin = temp + 1; 
        } 
    } 
} 

Upvotes: -2

Toby Speight
Toby Speight

Reputation: 30762

We need to decompose into two problems. We already have most of the solution to one problem (reversing a string); we just need to make it work with a substring. We do this mainly by removing the code that finds the end of the string:

/* reverse substring [left, right) in-place */
void reverseSubstring(char *left, char *right)
{
    while (left < --right) {
        char c = *right;
        *right = *left;
        *left++ = c;
    }
}

The other half of the problem is finding the boundaries between words. We can use isspace() to position start and end pointers in the right places, and call our reverseSubstring with them:

#include <ctype.h>
char *reversepPrint(char *const name)
{
    char *start = name;
    char *end;

    while (*start) {
        while (*start && isspace(*start)) {
            ++start;
        }
        end = start;
        while (*end && !isspace(*end)) {
            ++end;
        }
        reverseSubstring(start, end);
        start = end;
    }

    return name;
}

If you're also prohibited from using <ctype.h>, it isn't hard to write a simple isspace() of your own for this function.


Full program

/* reverse substring [left, right) in-place */
void reverse_substring(char *left, char *right)
{
    while (left < --right) {
        char c = *right;
        *right = *left;
        *left++ = c;
    }
}
    
#include <ctype.h>
/* reverse individual words in string */
/* word boundaries determined by isspace() */
char *reverse_words(char *const name)
{
    for (char *start = name, *end;  *start;  start = end) {
        while (*start && isspace(*start)) { ++start; }
        end = start;
        while (*end && !isspace(*end)) { ++end; }
        reverse_substring(start, end);
    }

    return name;
}

#include <stdio.h>
int main(void)
{
    char s[] = "Simon liebt Pizza!";
    printf("%s", reverse_words(s));
}

Upvotes: 3

Amir Ali
Amir Ali

Reputation: 11

Here's my little effort to the logic without using the string.h

#include <stdio.h>

char * reversepPrint( char *name )
{

    char *normal = name, *reverse = name;

    while ( *reverse ) ++reverse;

    if ( normal < reverse )
    {
        for ( ; normal < --reverse; ++normal  )
        {
            char c = *normal;
            *normal = *reverse;
            *reverse  = c;
        }
    }

    return name;
}

int main( void ) 
{
    char s[] = "Simon liebt Pizza!";
    int i;
    int num_of_spaces = 0;

    int length = 0;

    char *temp = &s;

    while(*temp!='\0'){
        temp++;
    }
    length = temp - s;


    for (i = 0; i<length; i++)
    {

        if (s[i]==' ')
        {
            num_of_spaces++;
        }
    }

    char x[num_of_spaces+1][100];
    i = 0;
    int index = 0,index1 = 0, k = 0;
    for(i = 0; i < length; i++)
    {
        if(s[i]!=' ')
        {
            x[k][index] = s[index1];
            index++;

        }else{

            x[k][index] = '\0';
            index = 0;
            k++;

        }
        index1++;
    }

    i = 0;
    for(i = 0; i<=num_of_spaces; i++)
    {
        printf("%s\n",reversepPrint(x[i]));
    }



    return 0;
}

This is what the code does

  • Given any string it will find its length without using strlen
  • Then, the code will find the total numbers of strings (Spaces between them)
  • After that, I am creating a 2d-array with the dimension [strings][100] (each string with length 100)
  • Copying the content separately to each string
  • then looping over the 2d array and calling the method.

Upvotes: 0

Chopin
Chopin

Reputation: 188

Your function reversepPrint reverse a string.

Since you want to reverse by word, you have to parse your string in order to apply your function reversepPrint on each word. For doing so, you can use the space character as a delimiter.

Upvotes: 0

Davide Spataro
Davide Spataro

Reputation: 7482

What I would do is the following:

  1. Create a function that reverse only n char of a string
  2. Use that to reverse words of the original array.
  3. Words can be easily identified because are blocks of non-null and non-space chars.

Something like the following should work (note that I did not test the code) and produces the following output: nomiS tbeil !azziP

//this is basically your original function
char * reverse_n( char *name, const int  len )
{
    char *normal = name, *reverse = name+len;

    if ( normal < reverse )
    {
        for ( ; normal < --reverse; ++normal  )
        {
            char c = *normal;
            *normal = *reverse;
            *reverse  = c;
        }
    }

    return name;
}

char * my_reverse( char *nname)
{
    char* name=nname;
    while(*name)
    {
        char* next = name;
        int l = 0;
        //find the next word and its length
        while(*next && *next!=' '){
            next++;
            l++;
        }
        //reverse it
        reverse_n(name, l);
        name=next;
        //skip the space
        if(*name)
            name++;
    }
    return nname;
}

Upvotes: 0

Related Questions