Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 递归删除字符串中的重复字符_C_Recursion_C Strings_Function Definition - Fatal编程技术网

C 递归删除字符串中的重复字符

C 递归删除字符串中的重复字符,c,recursion,c-strings,function-definition,C,Recursion,C Strings,Function Definition,我试图创建一个递归函数,从字符串中删除连续的重复字符。除了前几个字符外,它工作正常。例如,如果我的输入是mmmmm uuuu ooooo kkkllee oooll或类似的内容,则输出是MMuOKLE OL。正如你所看到的,除了前两个M,它工作得很好。我怎样才能使第一部分也能工作? 这是我的密码: #include <stdio.h> char* remove_duplicates (char* str){ if(*(str+1)!='\0'){ if(*s

我试图创建一个递归函数,从字符串中删除连续的重复字符。除了前几个字符外,它工作正常。例如,如果我的输入是
mmmmm uuuu ooooo kkkllee oooll
或类似的内容,则输出是
MMuOKLE OL
。正如你所看到的,除了前两个M,它工作得很好。我怎样才能使第一部分也能工作? 这是我的密码:

#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;
}
#包括
char*删除重复项(char*str){
如果(*(str+1)!='\0'){
如果(*str==*(str+1)){
*(str+1)=*(str+2);
删除重复项(str+1);
}
删除重复项(str+1);
}
返回str;
}
int main()
{
char sample[]=“mmmmm uuuu ooooo kkkllee oooll”;
printf(“旧的:|%s |\n”,示例);
printf(“新建:|%s |\n”,删除重复项(示例));
返回0;
}

我认为递归太复杂了

让我们从
str开头的2个光标开始

首先是字符串上的循环。 当我们没有到达字符串的结尾时,向前看
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: ||

我们得到了
AB

谢谢大家的帮助。正如您所说,我在纸上浏览了我的代码,并意识到问题在于它没有比较第一个M和最后一个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;
}
我是这样做的:

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

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

我在这里只是添加递归函数(语言:C++),而不是整个代码

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; 
}
void removeConsecutiveDuplicates(字符输入[]){
如果(输入[0]='\0'| |输入[1]='\0')返回;
if(输入[0]!=input[1])返回removeConSecuriveReplicates(输入+1);
其他的
{

对于(int i=1;iIn除了其他可能错误的内容外,如果将空字符串(
)传递给
删除重复项()
),会发生什么情况?将测试用例简化为查看问题所需的最小字符串。然后在纸上遍历它,并在调试器中逐步遍历。@SteveFriedl我将
传递给
删除重复项()
在main中。什么都没有发生。它会再次打印菜单。@gokbeykeskin-我相信您需要更仔细地研究一下这个问题。如果第一个字符是NUL字节,并且后面的所有内容都是随机垃圾,是什么导致函数停止?什么interest返回参数而不是让
void删除重复项(char*str)
?这使得第二次调用变得非常复杂?我的函数是一个if语句中的4行代码,并且是递归的。@abelenky请看David C.Rankin的评论,我认为递归在这个主题上并不简单,4行和一个大的三元数不确定它是否简单。有趣的是,它将非重复项转移到了t他结束并返回非重复项开始的字符串内的指针,但原始字符串(例如,如果您再次打印
sample
)仍包含重复项。@abelenky您提供了错误的代码。请尝试以下char sample[]=“AA”;删除重复项(sample);printf(\%s\“\n”,sample);@Vlad:My code确实就地修改了
sample
,但它返回一个指向数组正确部分的指针。您应该尝试
printf(“\%s\”\n”,删除重复项(sample));
然后您将看到返回值是正确的。@abelenky这是一种无效的方法。您必须从作为参数传递给函数的指针指向的原始字符串中删除重复项。@Vlad在问题描述中没有指定。我的返回值是正确的。逻辑是痛苦的
:)
--不过,所有带有多个递归调用的递归逻辑都是……做得很好。大家好,欢迎来到Stack Overflow!请阅读。感谢您提供答案,但您是否可以添加一个关于代码如何解决问题的解释?查看此页以获取有关格式化代码的帮助。
#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
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; 
}