C++ 当数组大小已满时,如何将圆形数组的内容复制到更大的数组中

C++ 当数组大小已满时,如何将圆形数组的内容复制到更大的数组中,c++,C++,我已经使用循环数组实现了一个队列ADT。但是,我希望能够在满时将圆形数组的所有内容复制到更大的数组中。我已经阅读了有关java的系统.ARayayRead,但是这个函数在C++中不存在。在下面的enqueue函数中,如果数组已满,它应该复制到更大的数组中,而不是抛出错误 void resize() { auto newMAX = 2 * MAX; Obj *cqueue_arr2 = new Obj[newMAX]; int i = 0;

我已经使用循环数组实现了一个队列ADT。但是,我希望能够在满时将圆形数组的所有内容复制到更大的数组中。我已经阅读了有关java的系统.ARayayRead,但是这个函数在C++中不存在。在下面的enqueue函数中,如果数组已满,它应该复制到更大的数组中,而不是抛出错误

 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`
我的代码:

template <class Obj>

class Circular_Queue
{
    int MAX;
    private:
    Obj *cqueue_arr;
    Obj *cqueue_arr2;
    int front, rear;
    public:
    Circular_Queue()
    {
        cqueue_arr = NULL;
        cout << "Enter size of the queue:";
        cin >> MAX;
        cqueue_arr = new Obj[MAX];
        rear = -1, front = -1;
    }

    ~Circular_Queue() {
        delete[]cqueue_arr;
    }

    void qfront() {
        if (front == -1)
        {
            throw QueueEmptyException();
        }
        cout << "Front item is : " << cqueue_arr[front] << endl;
    }

    //Insert into Circular Queue
    void enqueue(Obj item)
    {
        int i;

        if ((front == 0 && rear == MAX - 1) || (front == (rear + 1)% MAX))
        { 
            Obj* cqueue_arr2 = new Obj[MAX * 2];     // Creates a bigger array.
            for (int i = 0; i < (MAX * 2); i++) {   // This section doesnt workas intended.
                cqueue_arr2[i] = cqueue_arr[i];
            }

        }
        if (front == -1)
        {
            front = 0;
            rear = 0;
        }
        else
        {
            if (rear == MAX - 1)
                rear = 0;
            else
                rear = ((rear + 1) % MAX);
        }
        cqueue_arr[rear] = item;
        cout << "Insertion Success!!!\n";
        cout << "The number of space left in the queue is  ";
        cout << MAX - (rear + 1) << endl;
        cout << "                                       \n";
        cout << "Content of new array is:";
        for (int i = 0; i < MAX * 2; i++)
            cout << cqueue_arr[i] << " ";
    }

    // Delete from Circular Queue
    Obj dequeue()
    {
        if (front == -1)
        {
            throw QueueEmptyException();
        }
        cout << "Element deleted from queue is : " << cqueue_arr[front] << endl;
        if (front == rear)
        {
            front = -1;
            rear = -1;
        }
        else
        {
            if (front == MAX - 1)
                front = 0;
            else
                front = ((front + 1) % MAX);
        }
    }

    //Display Circular Queue

    void display()
    {
        int front_pos = front, rear_pos = rear;
        if (front == -1)
        {
            cout << "Cannot display, Queue is EMPTY!\n";
            return;
        }
        cout << "Circular Queue elements are:\n";
        if (front_pos <= rear_pos)
        {
            while (front_pos <= rear_pos)
            {
                cout << cqueue_arr[front_pos] << "  ";
                front_pos++;
            }
        }
        else
        {
            while (front_pos <= MAX - 1)
            {
                cout << cqueue_arr[front_pos] << "  ";
                front_pos++;
            }
            front_pos = 0;
            while (front_pos <= rear_pos)
            {
                cout << cqueue_arr[front_pos] << "  ";
                front_pos++;
            }
        }
        cout << endl;
    }
};
 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`

主要问题是访问数组时超出了范围。您应该循环使用现有的大小,而不是新的大小。另外,您只是在丢弃新数组,您需要删除旧数组并在新数组中交换,即

if ((front == 0 && rear == MAX - 1) || (front == (rear + 1)% MAX))
{ 
    auto newMax = MAX * 2;
    Obj* cqueue_arr2 = new Obj[newMax];     // Creates a bigger array.
    for (int i = 0; i < (MAX); i++) {   // loop over original array size, not new size
        cqueue_arr2[i] = cqueue_arr[i];
    }
    // remember to actually use the new array, and discard the old one.
    delete[] cqueue_arr;
    cqueue_arr = cqueue_arr2
    MAX = newMax;
}
 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`
另一方面,仅仅使用std::vector而不是Data[]将使所有这些都变得毫无意义。它将高效地自我扩展,尽可能避免与realloc类似的副本。它还将避免一些其他限制,例如,您当前的实现需要一个默认构造函数和复制赋值运算符,并且所有访问都将内联到指针算术,因此使用原始指针不会获得任何好处。实现基本上可以保持不变,除了不断增长的部分,它只是成为queue_vec.push_backval

 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`

此外,在构造函数中使用cin也是一种糟糕的做法。您应该只传递一个int作为参数。如果你愿意的话,你可以从cin的主页上读到。这样,您的类就可以在其他地方使用,而不会干扰IO

我希望它能给你一个解决问题的提示

 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`
首先,我推荐stl或boost中预先存在的数据类型,因为它已经过优化和稳定

 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`
第二,只是为了复制数组。。。我很乐意。 应提前分配TargetArray。但是,如果需要,可以在函数中分配它

    typedef Obj value_type;
    int Clone(Obj *&TargetArray) {
          unsigned int curArraySize=sizeof(value_type)*`YourArraySize'
          memcpy(TargetArray,cqueue_arr, curArraySize);
          TargetArray[curArraySize+1]=NULL;
          return curArraySize;
    }
 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`

祝你好运

谢谢约瑟夫·爱尔兰和邝春康。根据您的建议并进行进一步研究,我的代码按预期工作。这就是我所做的。
 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`
`

 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`

如图所示,两个整数变量控制新旧数组中项目的位置。这使得它非常适用于前面位置不总是索引为0的循环队列。复制完所有项目后,我在新数组中将索引设置为front=0和rear=MAX-1。希望这对其他人有所帮助。

这两个阵列的大小不同。为了避免未定义的行为,复制的元素数应该是较小数组中的元素数,而不是较大数组中的元素数。当然,还有管理两个数组的生命周期的问题,您的代码对此也不做任何处理。谢谢。我已经考虑过了。谢谢。这很有帮助。我没有注意到我在新数组而不是旧数组上循环。关于构造函数,我按照建议将MAX值作为参数传递。循环_Queueint MAX。。但是我在做循环队列cqi时出错了;在主程序中。错误消息:类Circular\u Queueadd显式Circular\u Queueint max=128不存在默认构造函数;作为构造函数,如果未指定,您将拥有一个默认构造函数,该构造函数将max设置为128。如果要在main中指定max,则需要如下构造它:Circular_Queue cqi1024;,或者你可以传递一个int。我也非常推荐。非常感谢你,你也可以通过两个memcpy调用来完成。
 void resize() {

    auto newMAX = 2 * MAX;

    Obj *cqueue_arr2 = new Obj[newMAX];
    int i = 0;                                 //  controls new array 

                                                            position
    int j = front;                            //  controls old array 
                                                           position
    bool rearReached = false;
    while (!rearReached) {
        rearReached = j % MAX == rear;        // is true when rear is 
                                                              reached
        cqueue_arr2[i] = cqueue_arr[j % MAX];
        i++;
        j++;
    }
    front = 0;
    rear = MAX - 1;
    cqueue_arr = cqueue_arr2;
    MAX = newMAX;`