简体   繁体   English

正确使用remove()函数?

[英]proper usage of the remove() function?

i'm working on this personal project and i'm a bit confused on how the remove() function works. 我正在从事这个个人项目,但对remove()函数的工作方式有些困惑。

header: 标头:

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

main (only including add() part) 主要(仅包括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

So for the add() function I had to take an int parameter add it to the array. 因此,对于add()函数,我必须采用一个int参数将其添加到数组中。 When it gets full I have to double the size of the array, copy the contents of the old array into the new one, redirect the data member pointer to the new array and then deallocate the array. 当它变满时,我必须将数组的大小加倍,将旧数组的内容复制到新数组中,将数据成员指针重定向到新数组,然后释放该数组。

For the remove() function I have to just take an int parameter and remove it from the IntSet by shifting over all the subsequent elements of the array. 对于remove()函数,我只需要获取一个int参数并将其移至数组的所有后续元素,即可将其从IntSet中删除。 Should I just use parts of my add function and pretty much tell it to do the opposite for my remove() function? 我是否应该只使用add函数的一部分,并告诉我对remove()函数做相反的事情? If not, how do I even begin to write the remove() function? 如果没有,我该如何开始编写remove()函数? I'll show the rest of my code if needed. 如果需要,我将显示其余的代码。 Thank you guys so much! 非常感谢你们!

Give this a try for removing: 尝试删除它:

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
}

I haven't tested, but in theory, this should locate the first instance of the int you need to remove, shift all values left by one spot (unless the int to remove is in the last index of the array), and then decrement the currentValue variable so the previous last index of the array is disregarded and can be overwritten. 我没有测试过,但是从理论上讲,这应该找到需要删除的int的第一个实例,将所有值左移一个点(除非要删除的int处于数组的最后一个索引中),然后递减currentValue变量,因此可以忽略数组的上一个最后一个索引,并且可以将其覆盖。 Anyway, sorry if that's a poor explanation, but it's not the easiest concept to explain. 无论如何,如果这是一个不好的解释,很抱歉,但这不是最容易解释的概念。 I attempted to document the code fairly well, so hopefully that will make sense :P Let me know if you have any questions and let me know if this works or doesn't work for you ( I find feedback to be very important. ) 我试图很好地记录代码,因此希望这是有道理的:P让我知道您是否有任何问题,并让我知道这是否对您有用( 我发现反馈非常重要。

EDIT: Also, I intended to mention this, but I forgot, so thank you, @Viet, for mentioning this in your answer, your add() function does not seem to handle cases when the currentValue is less than the size of the array. 编辑:另外,我打算提一下,但是我忘了,所以谢谢@Viet,在您的回答中提到这一点,当currentValue小于数组的大小时,您的add()函数似乎无法处理情况。 I assume you are already handling that and you just omitted the else statement that takes care of it? 我假设您已经在处理它,而您只是省略了处理它的else语句?

EDIT #2: The following is code to properly handle adding new elements to the array: 编辑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++;
}

Again, I have not tested this code, but let me know if it works or does not work for you. 同样,我尚未测试此代码,但请告诉我它是否对您有用。 Also, I modified the line that makes a new array ( int *temp = new int[sizeOfArray]; ) to now handle errors if memory cannot successfully be allocated. 另外,我修改了创建新数组的行( int *temp = new int[sizeOfArray]; ),以在无法成功分配内存的情况下处理错误。 To do this I am using the (nothrow) object (more on that on this CPlusPlus page ). 为此,我使用了(nothrow)对象(有关此CPlusPlus页的更多信息 )。 If allocation fails, a temp is set to a null pointer. 如果分配失败,则将temp设置为空指针。 Without this, the method would instead throw a bad_alloc exception or the program would terminate. 否则,该方法将引发bad_alloc异常,否则程序将终止。 That's not very graceful, so I prefer properly handling the error (and handling it in a way that is less strenuous on the calling function). 那不是很优雅,因此我更喜欢正确处理错误(并以对调用函数不太费劲的方式来处理错误)。 To use this, you will need to include the <new> header (which is where nothrow is defined). 要使用此功能,您将需要包含<new>标头(在其中定义了nothrow )。

Is your class is a set or a list? 您的课程是集合还是列表? If your class is a set, it mean there are no same numbers in your class Example: a set {1, 2, 3}, a list: {1, 2, 3, 1, 3, 2} 如果您的班级是一个集合,则意味着您的班级中没有相同的数字例如:一组{1,2,3},一个列表:{1,2,3,1,3,2}

About your add function, i have some comments: 关于您的添加功能,我有一些评论:

  • You does not check new element exist in your set 您不检查集合中是否存在新元素
  • You does not increase current size and set value for new element in your set 您不会增加集合中新元素的当前大小和集合值
  • You can use memcpy function to copy old data to new data pointer 您可以使用memcpy函数将旧数据复制到新数据指针

About remove function, i have some ideas: 关于删除功能,我有一些想法:

  • At first, you must find the position of number which need to be delete in current set 首先,必须找到当前集合中需要删除的数字的位置
  • After that, you remove that number by shift left all member from next position of number which need to be delete to the left position. 之后,通过将所有成员从需要删除的数字的下一个位置向左移动,来删除该数字。 And you must decrease current size by 1 并且您必须将当前大小减小1

Example: you have a set {1, 2, 3, 4}, current size is 4. And you want to remove a number "2" 示例:您有一个集合{1、2、3、4},当前大小为4。并且您要删除数字“ 2”

  • First, you find the position of 2 in your set. 首先,您在集合中找到2的位置。 It is 1 (because the start index of array is start from 0) 它是1(因为数组的起始索引是从0开始)
  • Second, you remove it by pushing back all the values from next position on the front of its in your set. 其次,通过从集合中其前面的下一个位置推回所有值来删除它。 Ex: the value of position 1 replaced by value 3, the value of position 2 replaced by value 4 例如:位置1的值替换为值3,位置2的值替换为值4
  • Finally, you decrease current size by 1. Now, current size is 3, and you have a new set {1, 3, 4} 最后,将当前大小减小1。现在,当前大小为3,并且有一个新集合{1、3、4}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM