1
#include <stdio.h>

int main(void)
{
  int i,j;
  int wordstart = -1;
  int wordend = -1;
  char words[]= "this is a test";
  char temp;

  // Reverse each word
  for (i = 0; i < strlen(words); ++i)
  {
    wordstart = -1;
    wordend = -1;
    if(words[i] != ' ') 
      wordstart = i;
    for (j = wordstart; j < strlen(words); ++j)
    {
      if(words[j] == ' ')
      {
        wordend = j - 1;
        break;
      }
    }
    if(wordend == -1)
      wordend = strlen(words);
    for (j = wordstart ; j <= (wordend - wordstart) / 2; ++j)
    {
      temp = words[j];
      words[j] = words[wordend - (j - wordstart)];
      words[wordend - (j - wordstart)] = temp;
    }
    i = wordend;
    printf("reversed string is %s:", words);
  }
}

I tried in this way but i am getting this output:
siht is a test
my expected output is:
test a is this

I would appreciate if some one could come with a different approach for which time complexity is very less or correct me if it is the right approach. Thanks

LihO
  • 41,190
  • 11
  • 99
  • 167
GEEK max
  • 191
  • 2
  • 2
  • 11

12 Answers12

1

Simply we can just use a n*1 2D character array tailored to suit our needs!!!

#include <stdlib.h>

int main()
{
    char s[20][20];
    int i=0, length=-1;
    for(i=0;;i++)
    {
        scanf("%s",s[i]);
        length++;
        if(getchar()=='\n')
            break;
    }
    for(i=length;i>=0;i--)
        printf("%s ",s[i]);
    return 0;
}
Allan Pereira
  • 2,572
  • 4
  • 21
  • 28
Sriram Jayaraman
  • 800
  • 1
  • 8
  • 15
1

You can create a double linked list as a base data structure. Then, iterate through the words and insert them in the list as you find them.

When you reach the end of the sentence, simply traverse the list backwards and print the words as you go through them

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • iam a beginner in c I do not know the application of linked list so can u point out the mistake in my program or suggest me different approach other than linked lists – GEEK max Mar 09 '12 at 08:07
  • 2
    @GEEKmax have you debugged your code to see what's wrong with it. Please don't start your StackOverflow experience thinking we're here to do homework for you. We can help you on specific problems. – Luchian Grigore Mar 09 '12 at 08:10
  • @Lucian Grigore sorry that is not my intention i am begineer in C it will take me an hour atleast to debug this – GEEK max Mar 09 '12 at 08:21
1

Perhaps this belongs on the code review site instead?

Your approach seems very efficient to me (except that I would only call strlen(words) once and save the result in a register).

Two possible bugs look like:

wordend = strlen(words);

should be

wordend = strlen(words)-1;

and

for(j = wordstart ; j <= (wordend - wordstart) / 2 ; ++j) {

should be

for(j = wordstart ; j <= (wordend + wordstart) / 2 ; ++j) {

Final code looks like (with some extra {}):

    #include <stdio.h>
    int main(int argc,char *argv[])
    {
        int i,j;
        char words[]= "this is a test";
        int L=strlen(words);

        // Reverse each word
        for(i = 0; i < L; ++i) {
          int wordstart = -1;
          int wordend = -1;
          if(words[i] != ' ') 
          {
            wordstart = i;

            for(j = wordstart; j < L; ++j) {
              if(words[j] == ' ') {
                wordend = j - 1;
                break;
              }
            }
            if(wordend == -1)
              wordend = L-1;
            for(j = wordstart ; j <= (wordend + wordstart) / 2 ; ++j) {
              char temp = words[j];
              words[j] = words[wordend - (j - wordstart)];
              words[wordend - (j - wordstart)] = temp;
            }
            i = wordend;
          }
        }
        printf("reversed string is %s:",words);
        return 0;   
    }
Peter de Rivaz
  • 33,126
  • 4
  • 46
  • 75
0
 #include <iostream>
 #include <string>   
  using namespace std;
  char* stringrev(char s[], int len)
  {
    char *s1 = (char*)malloc(len+1);
    int i=0;
    while (len>0)
    {
      s1[i++] = s[--len];
    }
   s1[i++] = '\0';
    return s1;   
  }

   void sentrev(char s[], int len)
 {
    int i=0; int j=0;
     char *r = (char*)malloc(len+1);
     while(1)
     {
     if(s[j] == ' ' || s[j] == '\0')
     {
       r = stringrev(s+i, j-i);
       i = j+1;
       cout<<r<<" ";
     }
    if (s[j] == '\0')
    break;
    j++;
   }

 }


int main()
{
char *s = "this is a test";
char *r = NULL;
int len = strlen(s);
cout<<len<<endl;
r = stringrev(s, len);
cout<<r<<endl;
sentrev(r, len);
return 0;
}

The above code snap reverse the sentence, using char *r and printing cout<

kriya
  • 11
  • 2
0
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
char st[50], rst[50];
printf("Enter the sentence...\n");
gets(st);
int len=strlen(st), p;
int j=-1,k;
p=len;
for(int i=(len-1); i>=0; i--)
{
    //searching for space or beginning
    if(st[i]==' ')
    {
        //reversing and storing each word except the first word
        for(k=i+1;k<p;k++)
        {
            //printf("%c",st[k]);
            rst[++j]=st[k];
        }
        j++;
        rst[j]=' ';
        printf("\n");
        p=i;
    }
    else if(i==0)
    {
        //for first word
        for(k=i;k<p;k++)
        {
            //printf("%c",st[k]);
            rst[++j]=st[k];
        }
    }

}
printf("Now reversing the sentence...\n");
puts(rst);
return 0;
}
0

Use a main for loop to traverse till the end of the sentence: Copy the letters in a string until you find a space. now call add@beginning function and in that function add the string each time you pass a string to the linked list. print the contents of the linked list with a space inbetween to get the expected output

Patrick Trentin
  • 7,126
  • 3
  • 23
  • 40
sandy
  • 1
0

My code,just traverse from the last and if you find a space print the characters before it,now change the end to space-1;This will print till the second word,finally just print the first word using a single for loop.Comment for alter approach.

Program:

#include<stdio.h>
int main()
{
 char str[200];
int i,j,k;
scanf("%[^\n]s",&str);
for(i=0;str[i]!='\0';i++);
i=i-1;
for(j=i;j>=0;j--)
{
    if((str[j])==' ')
    {
        for(k=j+1;k<=i;k++)
        {
            printf("%c",str[k]);
        }
        i=j-1;
        printf(" ");
    }

}
for(k=0;k<=i;k++)
{
    printf("%c",str[k]);
}
}
joness
  • 65
  • 1
  • 6
0
using stack 

#include <iostream>  
#include <stdio.h>
#include <stack>

int main()
{ 

    std::stack<string> st;
    char *words= "this is a test";
    char * temp =   (char *)calloc(1, sizeof(*temp));
    int size1= strlen(words);
    int k2=0;
    int k3=0;
    for(int i=0;i<=size1;i++)
    {
       temp[k2] = words[i];
       k2++;
        if(words[i] == ' ')     
        {  
            k3++;
            if(k3==1)
                temp[k2-1]='\0';

            temp[k2]='\0';
            st.push(temp);
            k2=0;           
        }
        if(words[i] == '\0')
        {
            temp[k2]='\0';
            st.push(temp);
            k2=0;
            break;
        }               
    }

  while (!st.empty())
  {
       printf("%s",st.top().c_str());
        st.pop();
  }
0

Start tokenizing the line from the last character and continue to the first character. Keep one pointer anchored at the base of the current word, and another pointed which will decrease while a word start is not found. When you find a word start while scanning like this, print from the word start pointer to the word end anchor. Update the word end anchor to the previous character of the current word start char.

You might want to skip the blankspace characters while scanning.

UPDATE

This is a quick implementation:

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define MAX_BUF 256

void show_string (char *str, int i, int n)
{
  while (i <= n)
  {
    printf ("%c", str[i]);
    i++;
  }
}

int main (void)
{
  char str[MAX_BUF];
  int end_anchor, start_ptr;
  int state;

  printf ("\nEnter a string: ");
  scanf (" %[^\n]", str);

  start_ptr = strlen (str) - 1;

  end_anchor = start_ptr;
  state = 0;
  while (start_ptr >= -1)
  {
    switch (state)
    {
      case 0:
             if ((!isspace (str[start_ptr]) && (start_ptr >= 0)))
             {
               start_ptr--;
             }
             else
             {
               state = 1;
             }
             break;

      case 1:
             show_string (str, start_ptr + 1, end_anchor);
             state = 2;
             start_ptr--;
             printf (" ");
             break;

      case 2:
             if (!isspace (str[start_ptr]))
             {
               state = 0;
               end_anchor = start_ptr;
             }
             else
             {
               start_ptr--;
             }
             break;
    }
  }


  printf ("\n");
  return 0;
}

The end_anchor points to each end word, and the start_ptr finds the start of the word of which the end is held by end_anchor. When we find a word start (by blankspace characters or start_ptr = -1), we print all the characters from start_ptr + 1 to end_anchor. The + 1 is because of the implementation: start_ptr points to the blankspace character, and the print routine will print all the characters from i to n. Once we have detected one blank space we print it and we skip adjacent blankspaces (in case 2) and preserve only one which is manually printed. Once a non blankspace is detected, we have got another word end, for which we set the end_anchor to this index in the case 2, and set state = 0 , so that we can search for the word start again.

phoxis
  • 60,131
  • 14
  • 81
  • 117
  • u mean taking two pointers one initally pointed at the start and the other at the end i did not understand can u please say it more clearly – GEEK max Mar 09 '12 at 08:12
  • what does this line make scanf (" %[^\n]", str); – GEEK max Mar 09 '12 at 09:12
  • skip blank spaces at the beginning of the string and read until a `\n` is not found, ie. reads a string containing blankspaces. – phoxis Mar 09 '12 at 09:13
  • yea is there any thing understood from the syntax coz it is difficult to remember – GEEK max Mar 09 '12 at 09:21
  • you can use anything, like `fgets` to get the string, or what ever, this is not the main issue. – phoxis Mar 09 '12 at 11:44
0

I would use write function similar to strrchr for finding last occurence of ' ', if its found print word that follows, rewrite this ' ' with '\0' and repeat it in loop till no more words are found. At the end I would print the content of this string again because there is most likely no ' ' before the first word.

I would write own function instead of strrchr because strrchr calculates the lenght of the given string, which is redundant in this case. This length doesn't have to be calculated more than once.

Here's the code:

char* findLastWord(char* str, int* len)
{
    int i;
    for (i = *len - 1; i >= 0; --i)
    {
        if (str[i] == ' ')
        {
            str[i] = '\0';
            if (i < *len - 1)
            {
                *len = i - 1;
                return &str[i + 1];
            }
        }
    }
    return NULL;
}

int main (int argc, char *argv[])
{
    char str[] = " one two three  four five six ";
    int len = strlen(str);

    char* lastWord = findLastWord(str, &len);
    while (lastWord != NULL)
    {
        printf("%s\n", lastWord);
        lastWord = findLastWord(str, &len);
    }
    if (len > 1)
        printf("%s\n", str);
    return 0;
}

output:

six
five
four
three
two
one

Hope this helps ;)

LihO
  • 41,190
  • 11
  • 99
  • 167
0
if(words[i] != ' ') 
    wordstart = i;

This statement what about the else part? if words[i] == ' ', and wordstart remains -1. So maybe try to use:

while (words[i] && words[i] == ' ') ++i;
  if (!words[i])
      break;
wordstart = i;

Then you should output the result out of the i loop. Finally, if you want to get the result you expected, you should reverse the whole sentence once more, with the way you used in the loop.

Daybreakcx
  • 76
  • 2
0
#include<stdio.h>
#include<string.h>

void reverse(char *str, size_t len)
{
    char tmp;
    size_t beg, end;
    if (len <=1) return;

    for (beg=0,end=len; beg < --end ; beg++) {
        tmp = str[beg];
        str[beg] = str[end];
        str[end] = tmp;
    }
}

int main(void)
{
    char sentence[] = "one two three four five";
    size_t pos, len;

    printf("Before:%s\n",sentence);
    for (pos = len= 0;  sentence[pos]; pos += len) {
        pos += strspn( sentence+pos, " \t\n" );
        len = strcspn( sentence+pos, " \t\n" );
        reverse ( sentence + pos, len );
        }
    reverse ( sentence , pos );

    printf("After:%s\n",sentence);

    return 0;
}
wildplasser
  • 43,142
  • 8
  • 66
  • 109