如何从数组中删除所有具有相同值的结构

问题描述

我正在研究自己的C编程技能,但我有点遇到问题:

我有一系列Animal结构,可以向其中添加动物。值之一是animalId,但是不检查重复的ID。因此,例如,我可以添加三个具有相同ID的狗,但它们可以位于数组中的不同位置。

我正在尝试编写一个函数,该函数可让我从数组中删除具有相同ID的alle动物。使用下面的代码,该程序仅删除具有找到的ID的第一个动物。另外,当我尝试再次删除相同的ID时,程序找不到其余的ID。为了退货,我想退回被移除的动物总数。

你们能给我一些提示我做错了什么吗?

编辑:移动“ * 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循环并使用一会儿时间:

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,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},{ 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;
}