Search code examples
cchartransformationc-stringsfunction-definition

Replacing a sequence of ascending characters by ascii code with a specific pattern


I am doing some kind of challenge in C in the internet and got the following mission:

Given a string, that consists of some ascending characters one after the other (by ASCII value), return the same string, but replace the middle letters of the sequence with one minus sign

Example: Given the following input: dabcefLMNOpQrstuv567zyx

We expect the following output: da-cefL-OpQr-v567zyx

The code I've tried:



/* Importing useful libs */
#include <stdio.h>
#include <string.h>

/* Declaring boolean definitions */
typedef enum {
    false,
    true
}
bool_enum;

/* Declaring Max. Input Length */
#define MAX_INPUT_LENGTH 80
void sequence_replace(char string[]);

/* Main Function */
int main() {
    char input_str[MAX_INPUT_LENGTH];
    printf("Please enter the string you'd like to switch its sequences with the three char method: ");
    scanf("%s", input_str);
    sequence_replace(input_str);
    return 0;
}

void sequence_replace(char string[]) {

    int first_char, last_char;
    int slen = strlen(string);
    bool_enum sequence = false;

    for(int i = 0; i < slen; i ++) {
        int s1 = string[i];
        int s2 = string[i+1];
        if (s1 + 1 == s2) {
            if (sequence = false) {
                sequence = true;
                first_char = i;
            }
        }
        if (s1 + 1 != s2) {
            if (sequence = true) {
                last_char = i;
                string[first_char + 1] = '-';
                for(int j = first_char+2; j < last_char; j++) {
                    string[j] = '';
                }
            }
            sequence = false;
        }
    }

    printf("Sequences after replacement are: %s", string);
    
}

Basically what I tried to do, is in the sequence_replace function iterate over the string until I find one character whose ascii code + 1 equals to the ascii code of the next character, I change a boolean flag to true to show that I am inside a sequence as well as keeping the index of when the first character of the sequence showed up, then once it hits a character whose ascii code - 1 is not equal to the previous character ascii code, I then switch the character that comes next after the first character with '-' sign and then just run a loop until the end of the sequence to replace all other remaining chars with just an empty string. Unfortunately, doesn't seem to be working, Would like to get any help if possible.


Solution

  • For starters there is no need to introduce this typedef declaration

    /* Declaring boolean definitions */
    typedef enum {
        false,
        true
    }
    bool_enum;
    

    It is much better just to include the header <stdbool.h> and use names bool, false and true defined in the header.

    The function itself should be declared like

    char * sequence_replace(char string[]);
    

    Using the function strlen is redundant and inefficient.

    As it follows from the provided example you should check whether a current character is an alpha character or not.

    You may not declare integer character constants that do not contain a symbol like this

    string[j] = '';
    

    That is in C there are no empty integer character constants.

    Also there is a logical error in this if statement (apart from the typo in the inner of statement if (sequence = true) { where there is used the assignment operator = instead of the equality operator ==)

        if (s1 + 1 != s2) {
            if (sequence = true) {
                last_char = i;
                string[first_char + 1] = '-';
                for(int j = first_char+2; j < last_char; j++) {
                    string[j] = '';
                }
            }
            sequence = false;
        }
    

    It unconditionally write the symbol '-' even if there are only two characters that satisfy the condition

    s1 + 1 == s2
    

    In this case according to the provided example the symbol '-' is not inserted.

    Also for example the for loop will not process the tail of the string that represents an increased sequence of letters.

    The function can look the following way as shown in the demonstration program below.

    #include <stdio.h>
    #include <ctype.h>
    
    char * sequence_replace( char s[] )
    {
        char *p = s;
    
        for ( char *q = s; *q; )
        {
            *p++ = *q++;
    
            char *current = q;
            while (isalpha( ( unsigned char )q[-1] ) &&
                isalpha( ( unsigned char )q[0] ) &&
                ( unsigned char )( q[-1] + 1 ) == ( unsigned char )q[0])
            {
                ++q;
            }
    
            if (current != q)
            {
                if (q - current > 1)
                {
                    *p++ = '-';
                }
                *p++ = q[-1];
            }
        }
    
        *p = '\0';
    
        return s;
    }
    
    int main( void )
    {
        char s[] = "dabcefLMNOpQrstuv567zyx";
    
        puts( s );
        puts( sequence_replace( s ) );
    }
    

    The program output is

    dabcefLMNOpQrstuv567zyx
    da-cefL-OpQr-v567zyx