Рекурсивное удаление повторяющихся символов в строке - PullRequest
3 голосов
/ 29 апреля 2020

Я пытаюсь создать рекурсивную функцию, которая удаляет последовательные повторяющиеся символы из строки. Работает нормально, кроме первых нескольких символов. Например, если мой ввод MMMMMuuuuuOOOOOKKKKLLLEE OOOOLLL или что-то в этом роде, вывод MMuOKLE OL. Как видите, кроме первых двух М, все работает отлично. Как я могу сделать эту работу для первой части тоже? Вот мой код:

#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;
}

Ответы [ 4 ]

1 голос
/ 29 апреля 2020

Вот, пожалуйста.

#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;
}

Вывод программы:

MuOKLE
1 голос
/ 29 апреля 2020

Я сделал это так:

#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;
}

Вывод

OLD: |MMMMMuuuuuOOOOOKKKKLLLEE OOOOLLL|
NEW: |MuOKLE OL|
OLD: |AA|
NEW: |A|
0 голосов
/ 29 апреля 2020

Спасибо всем за помощь. Как вы сказали, я просмотрел свой код на бумаге и понял, что проблема в том, что он не сравнивает первый и последний M. Я добавляю новый оператор if if(*str==*(str-1)) *(str)=*(str+1);, и теперь он работает.

Теперь функция:

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;
}
0 голосов
/ 29 апреля 2020

Рекурсия слишком сложна, я думаю.

Давайте начнем с 2 курсоров в начале str

Сначала все oop в строке. Пока мы не достигаем конца *p строки, ожидаем p++

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

Если следующий символ совпадает с текущим, продолжайте поиск следующего другого символа.

current++;
*current = *p;

Если найден другой символ, просто поместите его после текущего.

#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: ||

Деталь с AAAB c для текущего

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

Получим AB

...