从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)->Age
,仅供参考以上是关于从c中的struct数组中删除重复名称[重复]的主要内容,如果未能解决你的问题,请参考以下文章