如何从数组中删除具有相同值的所有结构
How to remove all struct with same value from an array
我正在研究我的 C 编程技能,但我有点卡在一个问题上:
我有一个 Animal 结构数组,我可以向其中添加动物。其中一个值是 animalId,但是,没有检查重复的 id。因此,例如,我可以添加三只具有相同 ID 的狗,但它们可以位于数组中的不同位置。
我正在尝试编写一个函数,让我从数组中删除所有具有相同 ID 的动物。使用下面的代码,程序只会删除具有找到的 ID 的第一只动物。此外,当我再次尝试删除相同的 ID 时,程序找不到其余的。对于 return 我想 return 删除的动物总数。
你们能告诉我我做错了什么吗?
编辑:移动了行“*newNumberOfAnimalsPresent = numberOfAnimalsPresent - 1;”在 j 循环之外。
int removeAnimal(int animalId, Animal *animalArray, size_t numberOfAnimalsPresent, size_t *newNumberOfAnimalsPresent)
{
for (size_t i = 0; i < numberOfAnimalsPresent; ++i)
{
if (animalId == animalArray[i].Id)
{
for (size_t j = i; j < numberOfAnimalsPresent - 1; ++j)
{
animalArray[j] = animalArray[j + 1];
}
*newNumberOfAnimalsPresent = numberOfAnimalsPresent - 1;
}
}
return numberOfAnimalsPresent - *newNumberOfAnimalsPresent;
}
*newNumberOfAnimalsPresent = numberOfAnimalsPresent - 1;
应该在第 j 个循环之后去吗?
因为如果没有删除你只会迭代每个项目,我认为最好忘记 for 循环并使用 while 代替:
int removeAnimal(int animalId, Animal *animalArray, size_t numberOfAnimalsPresent, size_t *newNumberOfAnimalsPresent)
{
*newNumberOfAnimalsPresent = numberOfAnimalsPresent;
int i = 0;
while (1)
{
if (*newNumberOfAnimalsPresent <= i)
{
break;
}
Animal animal = animalArray[i];
if (animalId == animal.Id)
{
for (size_t j = i; j < *newNumberOfAnimalsPresent - 1; j++)
{
animalArray[j] = animalArray[j + 1];
}
(*newNumberOfAnimalsPresent)--;
}
else
{
i++;
}
}
return numberOfAnimalsPresent - *newNumberOfAnimalsPresent;
}
使用两个计数器遍历数组。 check
始终递增,因此检查每个数组元素。 good
仅在没有匹配时递增,因此它反映了好的数组元素将被保留。
#include <stdio.h>
typedef struct {
int Id;
} Animal;
int removeAnimal(int animalId, Animal *animalArray, size_t numberOfAnimalsPresent, size_t *newNumberOfAnimalsPresent)
{
size_t good = 0;
size_t check = 0;
for ( good = 0, check = 0; check < numberOfAnimalsPresent; ++check)
{
if (animalId != animalArray[check].Id)//not a match
{
if ( good != check) {//not equal
animalArray[good] = animalArray[check];//make a copy
}
++good;//increment
}
}
*newNumberOfAnimalsPresent = good;
return check - good;
}
int main ( void) {
Animal pets[10] = {
{ 1}
, { 2}
, { 3}
, { 4}
, { 5}
, { 2}
, { 7}
, { 8}
, { 9}
, { 2}
};
int duplicates = 0;
size_t elements = 0;
size_t show = 0;
duplicates = removeAnimal ( 2, pets, 10, &elements);
printf ( "2 found %d times\n", duplicates);
while ( show < elements) {
printf ( "pet[%zu] id is %d\n", show, pets[show].Id);
++show;
}
return 0;
}
我正在研究我的 C 编程技能,但我有点卡在一个问题上:
我有一个 Animal 结构数组,我可以向其中添加动物。其中一个值是 animalId,但是,没有检查重复的 id。因此,例如,我可以添加三只具有相同 ID 的狗,但它们可以位于数组中的不同位置。
我正在尝试编写一个函数,让我从数组中删除所有具有相同 ID 的动物。使用下面的代码,程序只会删除具有找到的 ID 的第一只动物。此外,当我再次尝试删除相同的 ID 时,程序找不到其余的。对于 return 我想 return 删除的动物总数。
你们能告诉我我做错了什么吗?
编辑:移动了行“*newNumberOfAnimalsPresent = numberOfAnimalsPresent - 1;”在 j 循环之外。
int removeAnimal(int animalId, Animal *animalArray, size_t numberOfAnimalsPresent, size_t *newNumberOfAnimalsPresent)
{
for (size_t i = 0; i < numberOfAnimalsPresent; ++i)
{
if (animalId == animalArray[i].Id)
{
for (size_t j = i; j < numberOfAnimalsPresent - 1; ++j)
{
animalArray[j] = animalArray[j + 1];
}
*newNumberOfAnimalsPresent = numberOfAnimalsPresent - 1;
}
}
return numberOfAnimalsPresent - *newNumberOfAnimalsPresent;
}
*newNumberOfAnimalsPresent = numberOfAnimalsPresent - 1;
应该在第 j 个循环之后去吗?
因为如果没有删除你只会迭代每个项目,我认为最好忘记 for 循环并使用 while 代替:
int removeAnimal(int animalId, Animal *animalArray, size_t numberOfAnimalsPresent, size_t *newNumberOfAnimalsPresent)
{
*newNumberOfAnimalsPresent = numberOfAnimalsPresent;
int i = 0;
while (1)
{
if (*newNumberOfAnimalsPresent <= i)
{
break;
}
Animal animal = animalArray[i];
if (animalId == animal.Id)
{
for (size_t j = i; j < *newNumberOfAnimalsPresent - 1; j++)
{
animalArray[j] = animalArray[j + 1];
}
(*newNumberOfAnimalsPresent)--;
}
else
{
i++;
}
}
return numberOfAnimalsPresent - *newNumberOfAnimalsPresent;
}
使用两个计数器遍历数组。 check
始终递增,因此检查每个数组元素。 good
仅在没有匹配时递增,因此它反映了好的数组元素将被保留。
#include <stdio.h>
typedef struct {
int Id;
} Animal;
int removeAnimal(int animalId, Animal *animalArray, size_t numberOfAnimalsPresent, size_t *newNumberOfAnimalsPresent)
{
size_t good = 0;
size_t check = 0;
for ( good = 0, check = 0; check < numberOfAnimalsPresent; ++check)
{
if (animalId != animalArray[check].Id)//not a match
{
if ( good != check) {//not equal
animalArray[good] = animalArray[check];//make a copy
}
++good;//increment
}
}
*newNumberOfAnimalsPresent = good;
return check - good;
}
int main ( void) {
Animal pets[10] = {
{ 1}
, { 2}
, { 3}
, { 4}
, { 5}
, { 2}
, { 7}
, { 8}
, { 9}
, { 2}
};
int duplicates = 0;
size_t elements = 0;
size_t show = 0;
duplicates = removeAnimal ( 2, pets, 10, &elements);
printf ( "2 found %d times\n", duplicates);
while ( show < elements) {
printf ( "pet[%zu] id is %d\n", show, pets[show].Id);
++show;
}
return 0;
}