我正在使用C ++数据结构类,我正在处理的问题是编写一个客户端函数来获取队列的长度而不使用函数原型更改队列:
int GetLength(QueType queue);
在我看来,这很简单,因为当你将队列对象传递给一个函数时,它正在使用一个副本,所以如果我迭代并出列直到它为空,我知道队列中有多少项。
QueType是文本提供的简单队列类型,ItemType定义为
typedef char ItemType;
我的简单驱动程序代码如下:
#include "QueType.h"
using namespace std;
int GetLength(QueType queue);
int main()
{
ItemType item; //typedef char
//initialize and fill the queue
QueType que(5);
que.Enqueue('A');
que.Enqueue('B');
que.Enqueue('C');
que.Enqueue('D');
que.Enqueue('E');
cout << "The length of the queue is " << GetLength(que) << endl;
while (!que.IsEmpty())
{
que.Dequeue(item);
cout << "Dequeue item of queue: " << item << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
int GetLength(QueType queue)
{
int cnt = 0;
ItemType item;
while (!queue.IsEmpty())
{
queue.Dequeue(item);
cout << "Dequeue item of local copy of queue: " << item << endl;
cnt++;
}
return cnt;
}
我的预期输出是:
Dequeue item of local copy of queue: A
Dequeue item of local copy of queue: B
Dequeue item of local copy of queue: C
Dequeue item of local copy of queue: D
Dequeue item of local copy of queue: E
The length of the queue is 5
Dequeue item of queue: A
Dequeue item of queue: B
Dequeue item of queue: C
Dequeue item of queue: D
Dequeue item of queue: E
Press any key to continue . . .
但我得到了这个:
Dequeue item of local copy of queue: A
Dequeue item of local copy of queue: B
Dequeue item of local copy of queue: C
Dequeue item of local copy of queue: D
Dequeue item of local copy of queue: E
The length of the queue is 5
Dequeue item of queue: p
Dequeue item of queue: ↨
Dequeue item of queue: 7
Dequeue item of queue:
Dequeue item of queue: ─
Press any key to continue . . .
QueType.h: 类FullQueue {};
class EmptyQueue
{};
typedef char ItemType;
class QueType
{
public:
QueType();
QueType(int max);
~QueType();
void MakeEmpty();
bool IsEmpty() const;
bool IsFull() const;
void Enqueue(ItemType newItem);
void Dequeue(ItemType& item);
private:
int front;
int rear;
ItemType* items;
int maxQue;
};
QueType.cpp:
#include "QueType.h"
QueType::QueType(int max)
{
maxQue = max + 1;
front = maxQue - 1;
rear = maxQue - 1;
items = new ItemType[maxQue];
}
QueType::QueType() // Default class constructor
{
maxQue = 501;
front = maxQue - 1;
rear = maxQue - 1;
items = new ItemType[maxQue];
}
QueType::~QueType() // Class destructor
{
delete [] items;
}
void QueType::MakeEmpty()
{
front = maxQue - 1;
rear = maxQue - 1;
}
bool QueType::IsEmpty() const
{
return (rear == front);
}
bool QueType::IsFull() const
{
return ((rear + 1) % maxQue == front);
}
void QueType::Enqueue(ItemType newItem)
{
if (IsFull())
throw FullQueue();
else
{
rear = (rear +1) % maxQue;
items[rear] = newItem;
}
}
void QueType::Dequeue(ItemType& item)
{
if (IsEmpty())
throw EmptyQueue();
else
{
front = (front + 1) % maxQue;
item = items[front];
}
}
代码获取长度,但显然队列已被修改。如果对象是通过引用传递的,那么队列将是空的但不是,它只是在每个队列位置都有垃圾。有些概念我不理解。任何帮助将不胜感激!
答案 0 :(得分:1)
如何覆盖Enqueue和Dequeue函数来递增和递减计数器......然后你就会知道队列中有多少项。
答案 1 :(得分:1)
更好的方法是在length
类中实现size
或QueType
函数,该函数返回队列中的项目数。
否则,您需要提供队列迭代器支持或foreach
功能。这是被动访问功能。您的GetLength
函数会从队列中删除项目,这可能不是一件好事。换句话说,要获取队列中的项目数,您需要删除队列中的项目。
答案 2 :(得分:0)
由于您无法更改基类,并且从其他答案和注释中看来,如果没有实现自己的复制构造函数,您实际上无法实现深层复制,我现在可以想到的唯一解决方法就是客户端功能你创建了另一个临时队列,当你从原始队列中取出一个项目时,将它排入tmp中,然后在你完成后再将它们移回原来的队列。
一些伪代码:
while(!Q.empty())
tmp.enqueue(Q.dequeue())
counter++
while(!tmp.empty())
Q.enqueue(tmp.dequeue())
此解决方案的成本为θ(2n*copy_cost)
,任何不使用内部计数器的解决方案都会花费O(n)
,并且由于您没有任何选项可以在不删除队列元素的情况下迭代队列,唯一的选择是将您的元素排入队列并对原始队列进行更改。
答案 3 :(得分:0)
这里的问题是当队列参数超出GetLength()客户端函数的范围时,正在调用QueType类析构函数。
QueType::~QueType() // Class destructor
{
delete [] items;
}
这将释放包含队列内部数据的动态分配的数组(项)。
你是正确的,因为GetLength()函数的队列参数是按值传递的,所以你不需要复制队列值,因为内部状态不会在原始变量中被修改。
你会发现,如果你在析构函数中注释掉delete [],你的GetLength()函数将按预期工作。