Inverse words in a sentence

I am currently passing through K.N. King C Programming: A Modern Approach. I missed the text for the 8th chapter (arrays), and I really want to go to chapter 9, but I still have to solve the so-called "programming projects" at the end of each chapter. Unfortunately, the 14th ... bothers me.

Write a program that changes words in a sentence.

Enter a sentence: you can cage a swallow can't you? Reversal of sentence: you can't swallow a cage can you? 

Tip. Use a loop to read characters one by one and store them in a one-dimensional char array. Stop the cycle for a period, question mark, or exclamation point ("trailing character"), which is stored in a separate char variable. Then use the second loop to search back through the array to start the last word. Print the last word, then search backward for the next word. Repeat until the beginning of the array is reached. Finally, type a trailing character.

I was thinking of defining a word as a sequence of characters between spaces. Therefore, when the space is reached, go back, print each character until another space is found. The first version of the program only printed the first word. In the current version, it prints only other words. I was stuck with this for two days, so any help is really appreciated. Here is my code as well as sample output. Hope I registered my code correctly. Thanks in advance!

The code

 /* Include the standard I/O library */ #include<stdio.h> /* Define main */ int main(void) { /** * Declare an array of characters storing the sentence, as well as * a character representing the current character under cursor and * the terminating character */ char sentence[100] = { ' ' }, c, tc; /** * Declare a loop counter already initialized at 0, an incremental * variable, as well as the size of the read sentence */ int i = 0, j = 1, size = 0; /* Get the sentence */ printf("Enter a sentence: \n"); for(c = getchar(); (c != '.') && (c != '!') && (c != '?') && (c != '\n'); c = getchar(), i++) { sentence[i] = c; /* Store the current character in the array */ size++; /* Increase the sentence size */ } tc = c; /* Get the terminating character */ /** * Go backward through the array, printing each sequence of characters * between spaces */ for(i = 99; i >= 0; i--) { if(sentence[i] == ' ') { while(sentence[i + j] != ' ') { printf("%c", sentence[i + j]); j++; } j = 1; /* Reset the incremental variable */ printf(" "); /* Print a tailing space */ } } /** * Delete the tailing blank space and print the terminating character, * as well as a new line */ printf("\b%c\n", tc); return 0; /* Return 0 upon successful program execution */ } 

Output:

http://drp.ly/1nYt5J

+6
c arrays
source share
10 answers

Another methodology to think about:

 you can cage a swallow can't you? uoy t'nac wollaws a egac nac uoy? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ you t'nac wollaws a egac nac uoy? ^^^ you can't wollaws a egac nac uoy? ^^^^^ you can't swallow a egac nac uoy? ^^^^^^^ you can't swallow a egac nac uoy? ^ you can't swallow a cage nac uoy? ^^^^ you can't swallow a cage can uoy? ^^^ you can't swallow a cage can you? ^^^ 

For every thing you want to change (whether it's a whole sentence or a word):

  • Find the beginning and the end
  • Change start and end characters
  • Move inward once
  • Continue driving until you reach the middle.

Since reversing a fragment of a string is a common operation, it makes sense to make it your own function. And since the only information that needs to be performed is:

  • line
  • starting index
  • end index

What do you think will be the parameters for the function?

Another common thing that needs to be done many times is to β€œfind” something, be it a space or a punctuation mark. You may need to write this yourself, or if you can use the library functions or want a hint, look:

 man strcspn 
+3
source share

press each word on the stack and read the stack from index from 0 to N-1

+5
source share

Here is an example that does what I mentioned. First cancel each word in place, and then change the entire line. Here is the reverse() function, which changes the line with the given delimiter character. You can expand the use of multiple delimiters if you wish.

 char *reverse(char *str, char delim) { char *end = strchr(str, delim); char *ret; char tmp; if (end == NULL) end = strchr(str, '\0'); ret = end + 1; end--; while (end > str) { tmp = *str; *str = *end; *end = tmp; end--; str++; } return ret; } 

Here is an example with a small sample program:

 int main(int argc, char **argv) { char *end = strchr(argv[1], '\0'); char *str = argv[1]; while (str < end) str = reverse(str, ' '); reverse(argv[1], '\0'); printf("%s\n", argv[1]); return 0; } 

Usage example:

 $ ./example "the quick red fox jumps over the lazy brown dog" dog brown lazy the over jumps fox red quick the 
+2
source share
 int main() { char sent[50],last,s; int i,j,length,k,temp,b; clrscr(); i=0; printf("Enter a sentence: "); sent[i]=getchar(); while(sent[i]!='\n'&&sent[i]!='.'&&sent[i]!='?'&&sent[i]!='!') { sent[++i]=getchar(); } last=sent[i];//storing last char b=i; //length of string printf("Reverse of sentence: "); for(;;) { k=b-1;// begin from last position temp=k; while(sent[k]!=' ' && k!=-1) k--; s=k;//storing space here b=s; for(j=b+1;j<=temp;j++) putchar(sent[j]); if(s!=-1) putchar(sent[s]); if(b==-1) break; } putchar(last); getch(); return 0; } 
+1
source share

Taking input as an array of characters and then changing the whole array. Following this, the opposite is word by word, where does the splitting of a sentence into words occur in ","? "," \ 0 ", etc. Hope this helps.

  void reverse(char s[],int start,int stop){ char t; while(start<stop){ t = s[start]; s[start]=s[stop]; s[stop]=t; start++; stop--; } } int main() { char str[100]; gets(str); int pos=0,begin=0,end; reverse(str,begin,strlen(str)-1); //since the last character is null while(pos<=strlen(str)){ if((str[pos]==' ')||(str[pos]=='\0')||(str[pos]=='?')||(str[pos]=='!')){ end = pos - 1; reverse(str,begin,end); begin = pos+1; //for the next word } pos++; } cout<<str; return 0; } 
+1
source share

I have not tried this. hope it would be helpful for u.

 char temp[100]; int j=0, k=100, l=0; for(i=size-1; i>=0; i--){ if(sentence[i] == ' ' || i == 0){ if(ki >= 2){// at least one character if(i==0) j = 0; else j = i+1; for( l=0; j < k; j++, l++){ temp[l] = sentence[j]; } temp[l] = '\0'; printf("%s ",temp); } k = i; } } printf("\b%c",tc); 
0
source share

Here is my answer

/ * write a program that changes words in a sentence:

Enter the sentence: you can score a swallow, right?

Reversal of sentence: you cannot assimilate the cell, can you?

Tip. Use a loop to read characters one by one and store them in a one-dimensional char array.

Hold the loop for a period, question mark, or exclamation point - ("terminating character"), which is stored as a separate char variable.

Then use the second loop to search back through the array to start the last word.

Print the last word, then search backward for the next word. Repeat until the end of the beginning of the array is reached.

Finally, type a trailing character.

 */ #include<stdio.h> int main() { int ch; char sentence[200]; //hard set a limit of 200 character sentence char word[10] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0'}; //hard set limit of 10 character words int i = 0; //character position in input int w = 9; //character position in word char terminator = '\0'; printf("Enter a sentence:"); while ( (ch=getchar()) != '\n' ) { if ( ch == '.' || ch == '?' || ch == '!') terminator = ch; else { sentence[i] = ch; i++; } // printf("%d",i); } sentence[i] = '\0';//set last character to null int x; for ( x=i ; x >= 0 ; x-- ) { if ( sentence[x] == ' ' ) { printf(" ");//print the space followed by what is in the word buffer/array // printf("word length %d ",w); printf("%c",word[0]); //probably should have a for loop here printf("%c",word[1]); printf("%c",word[2]); printf("%c",word[3]); printf("%c",word[4]); printf("%c",word[5]); printf("%c",word[6]); printf("%c",word[7]); printf("%c",word[8]); printf("%c",word[9]); w = 9 ; word[0] = '\0'; //fill the word buffer/array with null word[1] = '\0'; word[2] = '\0'; word[3] = '\0'; word[4] = '\0'; word[5] = '\0'; word[6] = '\0'; word[7] = '\0'; word[8] = '\0'; word[9] = '\0'; // printf("\n"); // printf("sentence position %d ",x); } else //assign the letters from sentence[] to letters in word[] { word[w] = sentence[x]; w--; // printf("word length %d ",w); // printf("%c",sentence[x]); } } //print the first word because im using space to delimit the words unless i have a space at the //beginning of the sentence the code above will skip the first word inputed printf(" ");//print the space followed by what is in the word buffer/array printf("%c",word[0]); printf("%c",word[1]); printf("%c",word[2]); printf("%c",word[3]); printf("%c",word[4]); printf("%c",word[5]); printf("%c",word[6]); printf("%c",word[7]); printf("%c",word[8]); printf("%c",word[9]); if ( terminator != '\0' ) //prints a . ? or ! if it is including in the inputed sentence printf("%c",terminator); printf("\n"); printf("\n"); return 0; 
0
source share

Reverse words in a line (words are separated by one or more spaces) - this problem can be handled in various ways, only a few of the solutions that I have seen so far use additional memory. The idea is to get the optimal solution, for example, without using an additional amount of memory (in place) with a time complexity of O (N).

So let's take an example, suppose the line is "Hello World" - and the expected O / P is "World Hello"

  • First, we just cancel the entire IN PLACE clause, for example, "dlroW olleH" (we used the XOR operation for the exchange. Please take a look at the Swap () method)
  • Now we increase the index and stop when we encounter "" (Space).
  • As soon as we are faced with any space, we know that we have received the word. Let the inverse function on this word and the inverse of this word be called. So, in this Case will be like "World olleH"
  • Now we go further and stop when our index reaches the length of the sentence.
  • As soon as we reach the end, take the last index -1 and undo the last word, so it will look like "World Hello".

One important point to note here, when we call the inverse function to cancel the word, we will have to provide the starting index and ending index of that particular word in the corresponding sentence.

Sample code will look like below. I have not tested with extreme cases - but this will provide a basic idea of ​​the approach.

  using System; namespace SampleString { class ReverseWordsInSetence { // Reverse words in a string (words are separated by one or more spaces). private static String GetReverseWordsInSetence(string sentence) { char[] stringArray = sentence.ToCharArray(); int len = sentence.Length; int startIndex = 0; Swap(ref stringArray, ref startIndex , len-1); startIndex = 0; for (int currentIndex = 0; currentIndex < len; currentIndex++) { if (stringArray[currentIndex].Equals(' ')) { Swap(ref stringArray, ref startIndex, currentIndex-1); } else if (currentIndex == len - 1) { Swap(ref stringArray, ref startIndex, currentIndex); } } return new string(stringArray); } private static void Swap(ref char[] a, ref int i, int j) { int tempIndex = j; while (i < j) { if (a[j].Equals('.')) { j--; } else { a[i] ^= a[j]; a[j] ^= a[i]; a[i++] ^= a[j--]; } } i = tempIndex + 2; } static void Main(string[] args) { Console.WriteLine(GetReverseWordsInSetence("Hello World.")); Console.ReadLine(); } } } 

code>

0
source share

The following code pushes the words on the stack, and then reads the stack back, and prompts Quonux .

 #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; } 
0
source share

So far, the answers have made alternative algorithms that can be sorted into two classes:

  • Cancel all sentence and all words in it. Some versions change the words first, while others reject the sentence first; the order in which these turns are applied does not matter. The net effect is that the words appear in the reverse order, but the characters inside each word are in their normal order.
  • Put the words on the stack, then grab them from the stack again so that the last word comes first.

Instead of suggesting another alternative algorithm (which is likely to fall into one of the two above categories), I will explain why the code in the original question does not work properly.

First, note that the code in the question is actually a variant of class 1. First, it cancels the entire sentence and then changes each word:

 /* Outer loop goes backwards through the array, effectively reversing the sentence */ for(i = 99; i >= 0; i--) { if(sentence[i] == ' ') { /* Inner loop goes forward, reversing the word again */ while(sentence[i + j] != ' ') { printf("%c", sentence[i + j]); j++; } j = 1; printf(" "); } } 

Besides some beginner mistakes, this is actually the best way to change sentence words. It does not use additional memory and does not waste time.

The respondent noted that the algorithm works as intended, except that it does not print the first word of the original sentence (which should be the last word). The reason for this is that array traversal stops at ' ' in both directions. When the outer loop reaches the beginning of the sentence, it does not find a space, because the first character of user input overwrites the space in sentence[0] :

 /* ... */ char sentence[100] = { ' ' }, c, tc; /* ... */ int i = 0, j = 1, size = 0; /* Get the sentence */ printf("Enter a sentence: \n"); for(c = getchar(); (c != '.') && (c != '!') && (c != '?') && (c != '\n'); c = getchar(), i++) { sentence[i] = c; /* Store the current character in the array */ size++; /* Increase the sentence size */ } 

Therefore, when i becomes 0 in the outer loop, there is no place, and the inner loop that should print a word starting with sentence[0] is never entered. i then decreases to -1 , and the outer loop ends.

You can test this without changing the code by simply running the program as a user. If you enter a space as the first character, the program response will be correct:

 Enter a sentence: you can cage a swallow can't you? you can't swallow a cage can you? 

There are two ways that you can ensure that the first word is included in your code. First, just always put a space at the beginning of your sentence array. You can do this by starting to copy user input to i = 1 instead of i = 0 :

 /** * Declare a loop counter already initialized at 1, an incremental * variable, as well as the size of the read sentence */ int i = 1, j = 1, size = 0; 

Another, slightly less elegant way would be to simply repeat the inner loop after the end of the outer loop:

 /** * Go backward through the array, printing each sequence of characters * between spaces */ for(i = 99; i >= 0; i--) { if(sentence[i] == ' ') { while(sentence[i + j] != ' ') { printf("%c", sentence[i + j]); j++; } j = 1; /* Reset the incremental variable */ printf(" "); /* Print a tailing space */ } } /* print the last word */ while(sentence[i + j] != ' ') { printf("%c", sentence[i + j]); j++; } 

You can make this less repetitive by dividing the inner loop into a new function. Here, the entire algorithm with the inner loop is factorized by the print_word function, skipping comments and blank lines:

 #include<stdio.h> void print_word(char[] sentence, int i) { int j = 1; while(sentence[i + j] != ' ') { printf("%c", sentence[i + j]); j++; } } int main(void) { char sentence[100] = { ' ' }, c, tc; int i = 0, j = 1, size = 0; printf("Enter a sentence: \n"); for(c = getchar(); (c != '.') && (c != '!') && (c != '?') && (c != '\n'); c = getchar(), i++) { sentence[i] = c; /* Store the current character in the array */ size++; /* Increase the sentence size */ } tc = c; /* Get the terminating character */ for(i = 99; i >= 0; i--) { if(sentence[i] == ' ') { print_word(sentence, i); printf(" "); /* Print a tailing space */ } } print_word(sentence, i); printf("\b%c\n", tc); return 0; /* Return 0 upon successful program execution */ } 

As a final note, there is one more thing you could do better. Right now, the outer loop begins with i = 99 , the last possible character in the sentence array. However, when reading user input, you updated i to indicate the next input position, so before starting the outer loop, i already points to the first character after the sentence. Why not use this and just start with i - 1 ?

0
source share

All Articles