C++数组队列实现方法错误

C++ Array Queue Implementation Method Errors

本文关键字:方法 错误 实现 队列 数组 C++      更新时间:2023-10-16

我正在尝试使用 C++ 中的数组实现队列。我一辈子都无法弄清楚为什么我的某些方法无法正常工作。我存在的方法找不到队列中的值,我的重复方法正在复制队列的后部而不是前面。重复方法应该获取队列前面的任何内容(假设它不是空的或满的(,复制该值,并将其放在队列的前面。我的将获取后面的值,复制它,并将其放在后面的一个位置。此外,排队方法未正确插入值。

#include <iostream>
#include "queue.h"
using namespace std;
static int nums[10];
int front = 0, rear = 0, sizeOfArray = 0;
int initialCapacity = 10;

int Enqueue(int num) {
if (sizeOfArray == initialCapacity) {
return -58;
}
for (int i = 0; i < initialCapacity; i++) {
if (nums[i] == num) {
return -62;
}
else {
nums[rear] = num;
rear = (rear + 1);
sizeOfArray++;
return 0;
}   
}
}
int Dequeue(int& num) {
if (sizeOfArray == 0) {
return -64;
}
front = (front + 1);
sizeOfArray--;
return 0;
}
int isEmpty() {
if (sizeOfArray == 0) {
return 1;
}
else {
return 0;
}
}
int Exists(int num) {
for (int i = 0; i < sizeOfArray; i++) {
int index = (front + i);
if (nums[index] == num) {
return 1;
}
else {
return 0;
}
}
return 0;
}
void Clear(void) {
front = rear = sizeOfArray = 0;
}
void Print(void) {
for (int i = 0; i < sizeOfArray; i++) {
cout << nums[i] << " ";
}
cout << endl;
}

int Duplicate(void) {
if (sizeOfArray == 0) {
return -78;
} 
if (sizeOfArray == initialCapacity) {
return -81;
}
int dupeNum;
dupeNum = nums[front];
nums[front + 1] = dupeNum;
sizeOfArray++;
return 0;
}

每当我在测试驱动程序中执行以下操作时: 排队 4 排队 5 存在 5 重复 打印

我得到这个输出:

测试 1 0 - 0 表示成功

测试 2 0 - 0 表示成功

测试 3 0 - 0 表示失败

测试 4 0 - 表示成功

44 0

首先,除非front始终为零,否则此代码不会执行您的预期操作:

int index = (front + i);
if (nums[index] == num) ...

这是因为您将尝试读取数组的末尾。您需要在数组的顶端进行环绕,如下所示:

int index = (front + i) % initialCapacity;

其他问题是:

  • 您的排队函数检查数组的所有元素中是否存在重复项,即使是那些技术上未填充的元素。您应该只检查填充的值(从frontfront + sizeOfArray,包装如上所述(。
  • 当您添加项目时,它也无法正确处理环绕。在最后一个数组项中插入元素后,rear的下一个值应回变为零:rear = (rear + 1) % initialCapacity
  • 同样,在
  • 调整front时,取消排队和重复功能。
  • 使用
  • 魔术返回码是一个坏主意,更好的方法是使用枚举(有关示例,请参阅下面的代码(。
  • 您的取消排队永远不会实际将 dequed 值放入您传入的引用参数中,这意味着它永远不会被更改。在增加front之前(确保已修复包装(,您可以执行num = nums[front]

可能还有其他问题,但你最大的问题是,尽管使用了某些C++的东西,但这并不是真正的C++代码。C++程序员可能犯的最大错误是成为 C+ 编码员,那个奇怪的品种在 C 和 C++ 世界之间迷失了一半:-(

您的队列实际上应该是一个类,而不仅仅是独立的函数。这样,您可以正确封装它并保护数据免受外部干扰。

我不会告诉你怎么做,因为这会使这个答案变得难以忍受,但是,你越早开始朝着这个方向前进,你就会成为一个更好的C++程序员。


例如,以下完整程序显示了执行此操作的一种方法。我不会把它作为你自己的工作,但了解C++程序员如何做到这一点是很有用的:

#include <cstdlib>
#include <memory>
template<class T>
class MyQ {
private:
size_t m_sz, m_first, m_next, m_used;
T *m_data;
public:
enum RetCode { OK, FULL, EMPTY };
MyQ(size_t sz = 10) : m_sz(sz), m_first(0), m_next(0), m_used(0), m_data(new T[sz]) {}
~MyQ() { delete [] m_data; }
enum RetCode Enqueue(T item) {
if (m_used == m_sz) return FULL;
m_data[m_next] = item;
m_next = (m_next + 1) % m_sz;
++m_used;
return OK;
}
enum RetCode Dequeue(T &item) {
if (m_used == 0) return EMPTY;
item = m_data[m_first];
m_first = (m_first + 1) % m_sz;
--m_used;
return OK;
}
};
// The class proper is above, the following is just a test harness.
#include <iostream>
int main() {
MyQ<int> x(6);
for (int i = 0; i < 7; i++) {
std::cout << "Enqueueing " << i << " returns " << x.Enqueue(i) << 'n';
}
std::cout << 'n';
int val;
for (int i = 0; i < 4; i++) {
MyQ<int>::RetCode rc = x.Dequeue(val);
if (rc == MyQ<int>::OK) {
std::cout << "Dequeueing returns " << rc << ", value was " << val << 'n';
} else {
std::cout << "Dequeueing returns " << rc << 'n';
}
std::cout << "Enqueueing " << (i + 7) << " returns " << x.Enqueue(i + 7) << 'n';
}
std::cout << 'n';
for (int i = 0; i < 7; i++) {
MyQ<int>::RetCode rc = x.Dequeue(val);
if (rc == MyQ<int>::OK) {
std::cout << "Dequeueing returns " << rc << ", value was " << val << 'n';
} else {
std::cout << "Dequeueing returns " << rc << 'n';
}
}
std::cout << 'n';
}

输出显示各种操作和错误条件:

Enqueueing 0 returns 0
Enqueueing 1 returns 0
Enqueueing 2 returns 0
Enqueueing 3 returns 0
Enqueueing 4 returns 0
Enqueueing 5 returns 0
Enqueueing 6 returns 1
Dequeueing returns 0, value was 0
Enqueueing 7 returns 0
Dequeueing returns 0, value was 1
Enqueueing 8 returns 0
Dequeueing returns 0, value was 2
Enqueueing 9 returns 0
Dequeueing returns 0, value was 3
Enqueueing 10 returns 0
Dequeueing returns 0, value was 4
Dequeueing returns 0, value was 5
Dequeueing returns 0, value was 7
Dequeueing returns 0, value was 8
Dequeueing returns 0, value was 9
Dequeueing returns 0, value was 10
Dequeueing returns 2