gokbeykeskin
gokbeykeskin

Reputation: 161

Recursively removing duplicate characters in a string

I'm trying to create a recursive function which removes the consecutive duplicate characters from a string. It works fine except the first few characters. For example if my input is MMMMMuuuuuOOOOOKKKKLLLEE OOOOLLL or something like this, output is MMuOKLE OL. As you can see except for the first two M's it works fine. How can I make this work for the first part too? Here is my code:

#include <stdio.h>

char* remove_duplicates (char* str){
    if(*(str+1)!='\0'){
        if(*str==*(str+1)){
            *(str+1)=*(str+2);
             remove_duplicates(str+1);
        }
        remove_duplicates(str+1);
    }
    return str;
}

int main()
{
    char sample[] = "MMMMMuuuuuOOOOOKKKKLLLEE OOOOLLL";

    printf("OLD: |%s|\n", sample);
    printf("NEW: |%s|\n", remove_duplicates(sample));

    return 0;
}

Upvotes: 4

Views: 752

Answers (5)

Hema Priya Velaga
Hema Priya Velaga

Reputation: 31

I am here just adding the recursive function (language: C++) and not the entire code.

void removeConsecutiveDuplicates(char input[]) {
   
    if(input[0] == '\0' || input[1]=='\0') return;
    if(input[0]!=input[1]) return removeConsecutiveDuplicates(input+1);
    else
    {
        for(int i=1;i<=strlen(input);i++)
        {
            input[i-1] = input[i];
        }
       return removeConsecutiveDuplicates(input);
    }  
    return; 
}

Upvotes: 0

abelenky
abelenky

Reputation: 64682

I did it this way:

#include <stdio.h>

char* remove_duplicates(char* str)
{
    if (*str)
    {
        char* dest = remove_duplicates(str + 1);
        str = (*str == *dest) ? dest : ((*(dest - 1) = *str), (dest - 1));
    }
    return str;
}

int main()
{
    char sample[] = "MMMMMuuuuuOOOOOKKKKLLLEE OOOOLLL";
    char sample2[] = "AA";

    printf("OLD: |%s|\n", sample);
    printf("NEW: |%s|\n", remove_duplicates(sample));

    printf("OLD: |%s|\n", sample2);
    printf("NEW: |%s|\n", remove_duplicates(sample2));

    return 0;
}

Output

OLD: |MMMMMuuuuuOOOOOKKKKLLLEE OOOOLLL|
NEW: |MuOKLE OL|
OLD: |AA|
NEW: |A|

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311018

Here you are.

#include <stdio.h>

char * remove_duplicates( char *s )
{
    if ( *s )
    {
        if ( *s == *( s + 1 ) )
        {
            *( s + 1 ) = *( s + 2 );
            remove_duplicates( s + 1 );
            remove_duplicates( s );
        }
        else
        {
            remove_duplicates( s + 1 );
        }           
    }

    return s;
}

int main(void) 
{
    char s[] = "MMMMMuuuuuOOOOOKKKKLLLEE";

    remove_duplicates( s );

    puts( s );

    return 0;
}

The program output is

MuOKLE

Upvotes: 1

&#212;rel
&#212;rel

Reputation: 7622

Recursion is too complicated I think.

Lets start with 2 cursor at the begining of the str

First a loop on the string. While we don't reach the end *p of the string look forward p++

while (*p++) {
    if (*p == *current)
        continue;

If next char is the same as the current continue to search the next different char.

current++;
*current = *p;

When a different char is found just put it after current.

#include <stdio.h>

char* remove_duplicates (char* str){
    char *p = str;
    char *current = p;
    while (*p++) {
        if (*p == *current)
            continue;
        current++;
        *current = *p;
    }

    return str;
}

int main()
{
    char sample[] = "MMMMMuuuuuOOOOOKKKKLLLEE OOOOLLL";

    printf("OLD: |%s|\n", sample);
    printf("NEW: |%s|\n", remove_duplicates(sample));
    printf("NEW: |%s|\n", remove_duplicates(""));

    return 0;
}


OLD: |MMMMMuuuuuOOOOOKKKKLLLEE OOOOLLL|
NEW: |MuOKLE OL|
NEW: ||

Detail with AAAB c for current

p
v
AAAB0
^
c

   p
   v
AAAB0
^
c

   p
   v
AAAB0
 ^
 c

   p
   v
ABAB0
 ^
 c

    p
    v
ABAB0
 ^
 c


    p
    v
ABAB0
  ^
  c


    p
    v
AB0B0
  ^
  c

We get AB

Upvotes: -1

gokbeykeskin
gokbeykeskin

Reputation: 161

Thank you all for your help. I walked through my code on paper as you said and realised the problem is it doesn't compare the first and last M. I add a new if statement if(*str==*(str-1)) *(str)=*(str+1); and it works now.

Now function is:

char* remove_duplicates (char* str){
    if(*(str+1)!='\0'){
        if(*str==*(str+1)){
            *(str+1)=*(str+2);
            remove_duplicates(str+1);
        }
        remove_duplicates(str+1);
    }
    if(*str==*(str-1)) *(str)=*(str+1);
    return str;
}

Upvotes: 0

Related Questions