Reversing an array of characters in place

I was asked this question in an interview

I had to swap the character array in my own place so as not to flip the entire character array.

if

char *ch="krishna is the best"; 

then I had to go back so that the result was like

  anhsirk si eht tseb 

I could not write the code in the interview. Can someone suggest me how to write to do this?

Can this be done with pointers?

if the interviewer did not tell me to change it to its place, then would it be easy to handle using another array of array symbol that would have a new character string after changing it?

+6
source share
9 answers
  char *ch="krishna is the best"; 

No, it could be a read-only literal pointer. Imagine that your interviewer knew C and wrote about it:

 char str[]="krishna is the best"; 

Then you can do something like this:

 #include <stdio.h> #include <string.h> #include <ctype.h> char* str_reverse_word (char* str) { char* begin; char* end; char* the_end; char tmp; while(isspace(*str)) /* remove leading spaces from the string*/ { str++; } begin = str; end = str; while(!isspace(*end) && *end != '\0') /* find the end of the sub string */ { end++; } the_end = end; /* save this location and return it later */ end--; /* move back 1 step to point at the last valid character */ while(begin < end) { tmp = *begin; *begin = *end; *end = tmp; begin++; end--; } return the_end; } void str_reverse_sentence (char* str) { do { str = str_reverse_word(str); } while (*str != '\0'); } int main (void) { char str[]="krishna is the best"; str_reverse_sentence (str); puts(str); } 
+2
source

Neither your interlocutor can write code for this.

 char *ch="krishna is the best"; 

you cannot change the data in the part of the memory you just read, and ch indicates the read-only memory.

Update: - Excerpt from N1548 (Β§6.7.9)

EXAMPLE 8
Declaration
char s[] = "abc", t[3] = "abc";
defines `` plain char array objects s ​​and t whose elements are initialized with string characters.
This declaration is identical.
char s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };
The contents of arrays are subject to change.

On the other hand, the declaration
char *p = "abc";
defines p with type ''pointer to char'' and initializes it, pointing to an object of type ''array of char'' with length 4, the elements of which are initialized with a character string literal. If an attempt is made to use p to change the contents of an array, the behavior is undefined .

You can see that swapping on these types of data is dangerous.

It is proposed to write the code as: -

char ch[]="krishna is the best"; and then apply an XOR swap every time a whitespace is encountered.

+7
source

It doesn’t sound too complicated if I understand him correctly. Pseudocode:

 let p = ch while *p != '\0' while *p is whitespace ++p let q = last word character starting from p reverse the bytes between p and q let p = q + 1 

Canceling a range of bytes is trivial if you have pointers to the beginning and end. Just loop halfway and replace bytes.

Of course, as indicated elsewhere, I assume that the buffer in ch actually being modified, which requires changing the code that you showed.

+4
source

You can swap word for word.

Just read the line before ' '(space) i.e. you get krishna and cancel this line and continue reading the original line to another ' '(space) and continue to cancel the line.

+1
source

Do I need to change the line in place, or is it just the result that needs to be undone?

If the first, then you have a problem. If the declaration is valid

 char *ch = "krishna is the best"; 

then you are trying to change the string literal, and the behavior when trying to change the string literal is undefined. If you work on a platform where string literals are stored in read-only memory, you will get a runtime error. You need to either change the announcement to

 char ch[] = "krishna is the best"; 

or select a dynamic buffer and copy the contents of the string into it

 char *ch = "krishna is the best"; char *buf = malloc(strlen(ch) + 1); if (buf) { strcpy(buf, ch); // reverse the contents of buf } 

to complete a U-turn.

If this is just the result that needs to be changed, then storage is not a big deal, you just need some pointers to keep track of the beginning and end of each substring. For instance:

 #include <stdio.h> #include <string.h> int main(void) { char *ch = "krishna is the best"; char *start, *end; // point to the beginning of the string start = ch; // find the next space in the string end = strchr(start, ' '); // while there are more spaces in the string while (end != NULL) { // set up a temporary pointer, starting at the space following the // current word char *p = end; // while aren't at the beginning of the current word, decrement the // pointer and print the character it points to while (p-- != start) putchar(*p); putchar(' '); // find the next space character, starting at the character // following the previous space character. start = end + 1; end = strchr(start, ' '); } // We didn't find another space character, meaning we're at the start of // the last word in the string. We find the end by adding the length of the // last word to the start pointer. end = start + strlen(start); // Work our way back to the start of the word, printing // each character. while (end-- != start) putchar(*end); putchar('\n'); fflush(stdout); return 0; } 

Probably the best way to do this is simply from the head.

+1
source

Not sure about the specific code right now, but here's how I did it (assuming you could write on top of the source variable).

1) Split a string into an array of words, using a space as a separator

2) Scroll the array and sort the words in reverse order

3) Rebuild the string and return the variable.

0
source

The following is an example of an in-place replacement using XOR:

 void reverseStr(char *string) { char *start = string; char *end = string + strlen(string) - 1; while (end > start) { if (*start != *end) { *start = *start ^ *end; *end = *start ^ *end; *start = *start ^ *end; } start++; end--; } } 

This, of course, assumes that the string is in writable memory, so don't complain that it isn't.

If you need to break the words first, then give me a few minutes and I will write something.

EDIT:

For words separated by a space ( 0x20 ), the following code should work:

 void reverseStr(char *string) { // pointer to start of word char *wordStart = string; // pointer to end of word char *wordEnd = NULL; // whether we should stop or not char stop = 0; while (!stop) { // find the end of the first word wordEnd = strchr(wordStart, ' '); if (wordEnd == NULL) { // if we didn't a word, then search for the end of the string, then stop after this iteration wordEnd = strchr(wordStart, '\0'); stop = 1; // last word in string } // in place XOR swap char *start = wordStart; char *end = wordEnd - 1; // -1 for the space while (end > start) { if (*start != *end) { *start = *start ^ *end; *end = *start ^ *end; *start = *start ^ *end; } start++; end--; } wordStart = wordEnd + 1; // +1 for the space } } 
0
source
 Here is my working solution -> #include<stdio.h> #include<ctype.h> #include<string.h> char * reverse(char *begin, char *end) { char temp; while (begin < end) { temp = *begin; *begin++ = *end; *end-- = temp; } } /*Function to reverse words*/ char * reverseWords(char *s) { char *word_begin = s; char *temp = s; /* temp is for word boundry */ while( *temp ) { temp++; if (*temp == '\0') { reverse(word_begin, temp-1); } else if(*temp == ' ') { reverse(word_begin, temp-1); word_begin = temp+1; } } /* End of while */ return s; } int main(void) { char str[]="This is the test"; printf("\nOriginal String is -> %s",str); printf("\nReverse Words \t -> %s",reverseWords(str)); return 0; } 
0
source
 Here is my working solution -> #include<stdio.h> #include<ctype.h> #include<string.h> char * reverse(char *begin, char *end) { char temp; while (begin < end) { temp = *begin; *begin++ = *end; *end-- = temp; } } /*Function to reverse words*/ char * reverseWords(char *s) { char *word_begin = s; char *temp = s; /* temp is for word boundry */ while( *temp ) { temp++; if (*temp == '\0') { reverse(word_begin, temp-1); } else if(*temp == ' ') { reverse(word_begin, temp-1); word_begin = temp+1; } } /* End of while */ return s; } int main(void) { char str[]="This is the test"; printf("\nOriginal String is -> %s",str); printf("\nReverse Words \t -> %s",reverseWords(str)); return 0; } 
0
source

Source: https://habr.com/ru/post/924073/


All Articles