remove()函数的正确使用

proper usage of the remove() function?

本文关键字:函数 remove      更新时间:2023-10-16

我正在做这个个人项目,我对remove()函数的工作方式有点困惑。

标题:

class IntSet {
public:
    IntSet(); //Constructor
    ~IntSet(); //Destructor
    int size() ; //
    bool isEmpty();
    bool contains(int number1);
    void add(int number2);
    void remove(int number2);
private:
    int* ptr; //pointer to the array
    int sizeOfArray; //current size of the array
    int currentValue; //number of values currently in IntSet
};

主要(仅包括add()部分)

        #include "IntSet.hpp"
    #include <iostream>
    IntSet::IntSet(){
        sizeOfArray = 10;
        currentValue = 0;
        ptr = new int[10];
    }

    IntSet::~IntSet(){
        delete[] ptr;
    }
    //returning the number of values in the IntSet
    int IntSet::size() 
    {
        return currentValue;
    }
    //Determining whether the stack is empty
    bool IntSet::isEmpty()
    {
        if (currentValue == 0)
            return true;
        else
            return false;
    }
    //defining contains() function 
    bool IntSet::contains(int number1)
    {
        for (int i = 0; i < currentValue; i++)
        {
            if (ptr[i] == number1)
                return true;
        }
        return false;
    }
        //defining add() function 
        void IntSet::add(int number2)
        {
            if (currentValue == sizeOfArray)
            {
                sizeOfArray = sizeOfArray * 2; //doubling size of arrayCapacity
                int* temp = new int[sizeOfArray]; //allocating new one that's twice as large
                for (int i = 0; i < currentValue; i++)
                {
                    temp[i] = ptr[i]; //copying old stuff into new one
                }
                delete[] ptr; //deallocate old array
                ptr = temp; //set ptr to new array
            }
        }
    //defining remove() function goes here

因此,对于add()函数,我必须使用一个int参数将其添加到数组中。当它变满时,我必须将数组的大小增加一倍,将旧数组的内容复制到新数组中,将数据成员指针重定向到新数组,然后取消分配数组。

对于remove()函数,我只需要取一个int参数,并通过对数组的所有后续元素进行移位来将其从IntSet中移除。我应该只使用add函数的一部分,并告诉它对remove()函数执行相反的操作吗?如果没有,我该如何开始编写remove()函数?如果需要,我会显示我的代码的其余部分。非常感谢你们!

尝试删除:

void IntSet::remove(int number2)
{
    bool bIntRemoved = false;
    for(int i=0; i < currentValue; i++){
        // check if we are currently searching or shifting
        if(!bIntRemoved){
            // still searching
            // check if we should remove int at current index
            if(ptr[i] == number2){
                // found the int to remove
                // We'll decrement i and set bIntRemoved = to true
                // So the else-if code handles shifting over the array
                    i--;
                bIntRemoved = true;
            }
        }else if(i < currentValue-1){
            // We have spots to shift
            // Check if this is the last index
            ptr[i] = ptr[i+1];
        } // else, we are at the last index and we have nothing to shift
    }
    if(bIntRemoved){
        // The int was successfully located and any necessary shifting has been
        // executed. Just decrement currentValue so the current last index will be
        // disregarded.
        currentValue--;
    } // else, the int to remove could not be located
}

我还没有测试过,但理论上,这应该找到你需要删除的int的第一个实例,将所有值移动一个点(除非要删除的int在数组的最后一个索引中),然后递减currentValue变量,这样数组的前一个最后一个索引就会被忽略,并且可以被覆盖。不管怎样,很抱歉,如果这是一个糟糕的解释,但这不是最容易解释的概念。我试图很好地记录代码,所以希望这将是有意义的:P如果你有任何问题,请告诉我,并让我知道这是否适用于你(我发现反馈非常重要。

编辑:此外,我本打算提到这一点,但我忘记了,所以感谢@Viet在您的回答中提到这一问题,当currentValue小于数组大小时,您的add()函数似乎无法处理这种情况。我想你已经在处理了,而你只是省略了else语句来处理它?

编辑#2:以下是正确处理向数组添加新元素的代码:

void IntSet::add(int number2){
    if (currentValue == sizeOfArray)
    {
        sizeOfArray = sizeOfArray * 2; //doubling size of arrayCapacity
        // nothrow is used below to allow for graceful error handling if there is not enough
        // ram to create the new array
        int* temp = new (nothrow) int[sizeOfArray]; //allocating new one that's twice as large
        // check if new int array could be create
        if(temp == nullptr){
            // new int array could not be created
            /** Possibly set an error flag here or in some way warn the calling function that
                the function failed to allocate the necessary memory space.
                I'll leave that up to you, OP. **/
            // Right now we'll just return without modifying the existing array at all
            return;
        }
        for (int i = 0; i < currentValue; i++)
        {
            temp[i] = ptr[i]; //copying old stuff into new one
        }
        delete[] ptr; //deallocate old array
        ptr = temp; //set ptr to new array
        // Now we'll just let the code below add the number to the array
    } // else we have enough space to add the number to the array
    ptr[currentValue] = number2;
    currentValue++;
}

同样,我还没有测试过这个代码,但请告诉我它是否适用于您。此外,我修改了生成新数组(int *temp = new int[sizeOfArray];)的行,以便在无法成功分配内存的情况下处理错误。要做到这一点,我使用(nothrow)对象(更多信息请参阅CPlusPlus页面)。如果分配失败,则将temp设置为空指针。否则,该方法将引发bad_alloc异常,否则程序将终止。这不是很优雅,所以我更喜欢正确处理错误(并以调用函数不那么费力的方式处理它)。要使用它,您需要包含<new>标头(定义nothrow的地方)。

您的类是集合还是列表?如果你的班级是一个集合,那就意味着你的班级里没有相同的数字示例:一个集合{1,2,3},一个列表:{1,2,3,1,3,2}

关于你的添加功能,我有一些评论:

  • 您没有检查集合中是否存在新元素
  • 您不增加集合中新元素的当前大小和集合值
  • 您可以使用memcpy函数将旧数据复制到新数据指针

关于删除功能,我有一些想法:

  • 首先,您必须找到当前集合中需要删除的数字的位置
  • 之后,您通过将所有成员从需要删除的编号的下一个位置向左移动到左侧位置来删除该编号。并且您必须将当前大小减小1

示例:您有一个集{1,2,3,4},当前大小为4。你想删除一个数字"2"

  • 首先,你找到2在你的集合中的位置。它是1(因为数组的起始索引是从0开始的)
  • 其次,通过将所有值从集合中它前面的下一个位置向后推,来移除它。例如:将位置1的值替换为值3,将位置2的值替换为由值4
  • 最后,将当前大小减小1。现在,当前大小为3,并且您有一个新的集合{1,3,4}