在C ++中增加循环队列的容量

时间:2014-11-16 02:38:21

标签: c++ arrays dynamic queue capacity

我正在学习队列,并且正在尝试编写一种方法来使用动态数组来更改循环队列的最大容量。这就是我的代码现在的样子。

void ArrayQueue::setCapacity(unsigned newCapacity){
if(newCapacity == 0 || newCapacity < this->getSize()){
    throw QueueException("setCapacity()", "invalid new capacity");
} else if(newCapacity != this->getSize()){
    Item * tempArray = new Item[newCapacity];
    for(unsigned i=0; i<newCapacity; i++){
        tempArray[i] = myArray[i];
    }
    Item * oldArray = myArray;
    myArray = tempArray;
    delete [] oldArray;
}
this->myCapacity = newCapacity;
}

然而,当我减少容量时,我失败断言以获取myFirst和myLast值。我知道我需要编写代码来解决条目已经包含的情况,但对如何这样做感到困惑。

我尝试传递的测试代码如下:

    ArrayQueue q5(10);
for (int i = 0; i < 10; i++){
    q5.append(i+1);
}
for (int i = 0; i < 7; i++){
    q5.remove();
}
assert( q5.getCapacity() == 10 );
assert( q5.getSize() == 3 );
assert( !q5.isEmpty() );
assert( !q5.isFull() );
assert( q5.getFirst() == 8 );
assert( q5.getLast() == 10 );

//reduce the capacity
q5.setCapacity(5);
assert( q5.getCapacity() == 5 );
assert( q5.getSize() == 3 );
assert( !q5.isEmpty() );
assert( !q5.isFull() );
assert( q5.getFirst() == 8 );
assert( q5.getLast() == 10 );

我通过了我的第一组断言,但第二个getFirst断言失败了。

你可以给我一个指向正确方向的指针吗?感谢。

3 个答案:

答案 0 :(得分:1)

我建议使用以下内容重写:

#include <algorithm>
//...
void ArrayQueue::setCapacity(unsigned newCapacity)
{
    if(newCapacity == 0 || newCapacity < this->getSize()){
        throw QueueException("setCapacity()", "invalid new capacity");
    ArrayQueue tempQ(newCapacity);
    for(unsigned i=0; i< capacity; i++)
        tempQ.append(myArray[i]);
    std::swap(myArray, tempQ.myArray);
    std::swap(capacity, tempQ.capacity);
    std::swap(size, tempQ.size);
}

这是如何工作的?好吧,我们创建一个具有必要容量的临时ArrayQueue。然后我们所做的就是将数据复制到临时对象。之后,我们用this换出临时对象。

完成。

临时对象以旧数据终止,this使用新数据设置。这是copy/swap成语的变体。这需要一个ArrayQueue的工作析构函数 - 一旦你有了它,那它就变成了小菜一碟。

请注意,如果有更多成员变量,则还需要进行交换。我只是换了你发布的那些。我猜你有一个size成员变量,所以如果你用不同的名字命名,那么用你用过的名字替换它。底线 - 用tempQ交换所有内容,你应该没问题。

如果你不知道std::swap做了什么,它会按照它说的做。它只是将两个项目相互交换 - 没有什么特别的,只是方便使用函数来执行此操作。

答案 1 :(得分:0)

for(unsigned i=0; i<newCapacity; i++){
    tempArray[i] = myArray[i];
}

如果您的新容量较大,则您将使用无效索引访问myArray

答案 2 :(得分:0)

尽管我可以找出你的问题,但除了你发布的代码片段之外,你引用了其他地方抛出的断言。由于您尚未发布有问题的代码,因此不太可能有人给您答案。

但是,我确实发现了您发布的代码片段中可能存在的错误。您的代码增加了数组的大小:

Item * tempArray = new Item[newCapacity];
for(unsigned i=0; i<newCapacity; i++){
    tempArray[i] = myArray[i];
}
Item * oldArray = myArray;
myArray = tempArray;
delete [] oldArray;

比如说,myArray的旧大小是20,你将它增加到40。

您将分配一个新的40元素tempArray。

然后继续将myArray中的前40个元素复制到tempArray。

未定义的行为。