3

I have a working piece of C code that completely removes every second char from a character array, making the original array half the size (half+1 if the size was odd)

..but I cannot figure out how it works.

void del_str(char string[]) {
    int i,j;
    for(i=0, j=0; string[i]!=0; i++) {
        if(i%2==0) {
            string[j++]=string[i];
        }
    }
    string[j]=0;
}

//
example input: 'abcdefgh'
output from that: 'aceg'
what I thought the output would be: 'aacceegg'

The line I don't understand is

string[j++]=string[i];

I can write code that omits every second char, so the output would be:

'a c e g '

but I can't wrap my head around this.

Alternatively, how would you write a program that completely deletes every n-th char and their space in the original array? (producing the same output as the above code)

zopad
  • 33
  • 4

3 Answers3

4

This code uses two position indexes, i and j. Initially, both indexes are initialized to zero. Index i is used for reading; index j is used for writing.

Index i is incremented at each step of the loop, because the increment i++ is in the header of the loop. Index j, on the other hand, is incremented every other iteration, because j++ happens only when i is even. Index i is always as close or closer to the end of the string than index j, because it moves "faster".

Null terminator is placed at the final position of j at the end of the loop to indicate the new position of string's end.

Perhaps it would be easier to see with a small example. Consider the initial string of "abcdef". Its representation in memory at the beginning of the algorithm is as follows:

'a' 'b' 'c' 'd' 'e' 'f' '\0'

Here is how it would change after each step of the loop:

'a' 'b' 'c' 'd' 'e' 'f' '\0'
'a' 'c' 'c' 'd' 'e' 'f' '\0'
'a' 'c' 'e' 'd' 'e' 'f' '\0'
'a' 'c' 'e' '\0' 'e' 'f' '\0'

Since C strings ignore everything after '\0', the "tail" of 'e' 'f' '\0' is not considered part of the string.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks a lot! The part I was missing was the '\0' being duplicated and finishing the string at half the size. – zopad Sep 14 '15 at 18:26
1

i and j are not the clearest variable names. Perhaps renamig j to something like output would help.

Note when j is updated, only when you're at an odd position. So i is walking through the whole list while j brings up the read copying something from i back to the jth position, overwriting what was there before. The last line, string[j]=0, terminates your string.

Paul Rubel
  • 26,632
  • 7
  • 60
  • 80
1

You are forgetting the if(i%2==0) which is crucial. This line basically skips every second character. Then, the line you have identified can be split in 2 parts:

string[j]=string[i]; // Overwrite the character at position j
j++;                 // Now increase j

The variable i keeps track of the position of the string you have reached while reading it; j is used for writing. In the end, you write 0 at position j to terminate the string.