从c中的struct数组中删除重复名称[重复]

Posted

技术标签:

【中文标题】从c中的struct数组中删除重复名称[重复]【英文标题】:Deleting duplicated name form struct array in c [duplicate] 【发布时间】:2021-07-23 13:45:43 【问题描述】:

我想做以下事情:应该可以删除具有指定名称的动物。如果存在更多同名动物,则应删除所有同名动物

我在 main.c 中的代码:

            case 3: //Remove Animal 
                printf ("remove Animal\n");
                char animalName[MaxNameLength];
                printf("Animal name to delete: \n");
                scanf("%s", animalName);

                deleteAnimalByName(animalName, &nrOfAnimals, animals);
                 printf("Animal has been removed");
                break;
           

还有我在 Administration.c 中的代码:

void deleteAnimalByName(char *animalName, int *nrOfAnimals, ANIMAL *animalArray)

    for(int i = 0; i < *nrOfAnimals; i ++)
   
       if(strcmp((animalArray + i)->Name, animalName) == 0)
       
           for(int j = i; j < *nrOfAnimals - 1; j++)
           
               (animalArray + j)->Age = (animalArray + j + i)->Age;
               strcpy((animalArray + j)->Name, (animalArray + j + i)->Name);
               (animalArray + j)->Species = (animalArray + j + i)->Species;
           
           *nrOfAnimals = *nrOfAnimals -1;
       
   


结果: 只有一个名字重复的动物被删除了..有人可以帮我解决这个问题吗?卡在这上面很长一段时间了。

【问题讨论】:

寻求调试帮助的问题必须提供complete minimal reproducible example。也就是说,任何人都可以完全按照所示运行以重现问题的最少完整代码量。 那么我应该添加我的整个代码吗? 请阅读链接。但不,不是整个代码。将您的代码减少到重现问题所需的最低限度。例如,如果有代码要求输入可以删除并替换为静态数据。删除任何其他并非绝对需要的代码。 我认为您在删除项目时跳过了对元素的检查。示例:数组 = [a, b, c, c,d];你删除 c, i = 2;然后你将它增加到 3,但你只是将第二个“c”分配给索引 2。所以它被跳过了。解决方案:删除项目时不要增加 i。 你的意思是在for循环中吗?因为我尝试删除 i++ 但这不起作用 【参考方案1】:

当您在数组中删除 2 个连续的结构时会出现问题:

array = ["dog", "cow", "cow", "fish"], toDelete="cow"

算法打印输出:

i:0; array = ["dog", "cow", "cow", "fish"]
i:1; array = ["dog", "cow", "cow", "fish"]
    match is found
    you delete "cow" at index 1
    new array = ["dog", "cow", "fish"]
i:2; array = ["dog", "cow", "fish"]
    notice here the second "cow" was skipped because the i was incremented

解决方案: 当您从数组中删除一个元素时,将 i 减 1,以重新检查该索引处的新元素。

【讨论】:

【参考方案2】:

您的代码有两个问题:

    您当前的复制代码实际上是将索引animals[i + i]...animals[i + *nrOfAnimals - 1] 移动到animals[i]...animals[i + *nrOfAnimals - 1]。目标部分很好,但源部分很明显是错误的;而不是(animalArray + i + j),你想要的是(animalArray + j + 1),因为你想用紧随其后的一项替换每一项; i + j 将是一些更大的索引,甚至可能超出数组的范围! 就像@sadsad 在 cmets 中所说,当您将数组的段向下移动到内存中时,您不会重新检查元素。解决此问题的一种方法是将if 替换为while:只要索引i 处的元素等于animalName,它将删除该元素,向下移动数组的其余部分,然后循环返回以再次检查新移动的元素。

【讨论】:

【参考方案3】:

我发现了问题,这是修复后的代码:

void deleteAnimalByName(char *animalName, int *nrOfAnimals, ANIMAL *animalArray)

    for(int i = 0; i < *nrOfAnimals; )
   
       if(strcmp((animalArray + i)->Name, animalName) == 0)
       
           for(int j = i; j < *nrOfAnimals - 1; j++)
           
               (animalArray + j)->Age = (animalArray + j + i)->Age;
               strcpy((animalArray + j)->Name, (animalArray + j + 1)->Name);
               (animalArray + j)->Species = (animalArray + j + 1)->Species;
           
           *nrOfAnimals = *nrOfAnimals -1;
       
       else
       
           i++;
       
   

i++ 是问题所在。

【讨论】:

你还有一个(animalArray + j + i)-&gt;Age,仅供参考

以上是关于从c中的struct数组中删除重复名称[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在c语言中输入数组两个数组,查找重复元素并输出怎么写啊

C语言,删除数组中的重复数字然后输出

如何在android中删除arraylist中的重复名称[重复]

从Ruby中的数组中删除重复元素

从 Kotlin 中的数组中删除重复项

从 C++ 中的数组中删除重复项 [关闭]