我使用循环数组实现了队列ADT。但是,我希望能够在完整时将圆形数组的所有内容复制到更大的数组。我已经阅读了Java中的system.arraycopy,但是这个函数在C ++中不存在。在下面的enqueue函数中,如果数组已满,而不是抛出错误,它应该复制到更大的数组中。
我的代码:
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;
}
};
答案 0 :(得分:1)
主要问题是您正在访问数组越界。你应该循环现有的大小,而不是新的大小。此外,您只是丢弃新数组,您需要删除旧数组并交换新数组,即
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;
}
顺便说一下,只使用std :: vector而不是Data[]
会让所有这些都没有用。如果可能的话,它会有效地增长,避免复制(类似于realloc())。它还将避免一些其他限制(例如,您当前的实现需要默认构造函数和复制赋值运算符),并且所有访问都将内联到指针运算,因此您不会通过使用原始指针获得任何收益。实施可以在很大程度上保持不变,除了增长部分,它只是queue_vec.push_back(val);
。
此外,在构造函数中使用cin
是不好的做法。您应该只传递int
作为参数。如果您愿意,可以在cin
中从main()
阅读该内容。这样你的类就可以在其他地方使用而不会干扰IO。
答案 1 :(得分:0)
我希望它会给你一个解决它的暗示。
首先,我建议使用stl或boost中预先存在的数据类型,因为它已经过优化和稳定。
第二,只是为了复制数组...我会这样做的。 (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;
}
祝你好运
答案 2 :(得分:0)
谢谢Joseph Ireland和Kwang-Chun Kang。根据您的建议并进行进一步研究,我的代码按预期工作。这就是我做的。 `
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。希望这有助于其他人。