问题描述
我在 Xcode 中插入“merge_queues”函数时遇到了一些问题。
这是使用模板的队列
#include "Problem1.hpp"
using namespace std;
const int DefaultSize = 10;
template <class T>
class Queue
{
public:
Queue(int queueCapacity = DefaultSize);
void getSize();
bool IsFull();
T &Front() const;
void push (const T& item);
bool IsEmpty();
T* pop(T&);
// if IsEmpty(),then QueueEmpty(); else remove and return the topmost element of the Queue
void QueueEmpty() {cout << "empty" << endl;};
void QueueFull() {cout << "full" << endl;};
void merge_queues(T &queue1,T &queue2);
void Output();
private:
int front;
int rear;
T *queue;
int capacity;
};
这里是merge_queues函数:
template <class T>
void Queue<T>::merge_queues(T &queue1,T &queue2) {
Queue<T> merged_queue;
// inserting in final queue
while(!IsEmpty() || !queue1.IsEmpty()) {
// inserting element of q1 if q1 is non-empty
if(!IsEmpty()) {
merged_queue.push(Front());
pop();
}
// inserting element of q2 if q2 is non-empty
if(!queue1.IsEmpty()) {
merged_queue.push(queue1.Front());
queue1.pop();
}
}
return merged_queue;
}
它在我的 Xcode 上没有任何错误,
但是我不知道如何在 main 函数中使用,有人可以帮我弄清楚吗?
这是我的主要功能
int main()
{
int x;
Queue<int> q1(5);
Queue<int> q2(6);
Queue<int> q3(11);
cout<<"queue1:\n";
q1.Output();
q1.getSize();
q1.push(1);
q1.Output();
q1.getSize();
q1.push(2);
q1.Output();
q1.getSize();
q1.push(3);
q1.Output();
q1.getSize();
q1.push(4);
q1.Output();
q1.getSize();
q1.push(5);
q1.Output();
q1.getSize();
cout<<"queue2: \n";
q2.Output();
q2.getSize();
q2.push(6);
q2.Output();
q2.getSize();
q2.push(5);
q2.Output();
q2.getSize();
q2.push(4);
q2.Output();
q2.getSize();
q2.push(3);
q2.Output();
q2.getSize();
q2.push(2);
q2.Output();
q2.getSize();
q2.push(1);
q2.Output();
q2.getSize();
q2.pop(x);
q2.Output();
q2.getSize();
merge_queues(q1,q2);
}
merge_queues(q1,q2)发生错误;
如何重写 merge_queues 以将两个队列合并为一个。
谢谢。:)
我尝试了另一种方法 将函数 merge_queues 更改为
template <class T>
void Queue<T>::merge_queues(T &queue1) {
Queue<T> merged_queue;
// inserting in final queue
while(!IsEmpty() || !queue1.IsEmpty()) {
// inserting element of q1 if q1 is non-empty
if(!IsEmpty()) {
merged_queue.push(Front());
pop();
}
// inserting element of q2 if q2 is non-empty
if(!queue1.IsEmpty()) {
merged_queue.push(queue1.Front());
queue1.pop();
}
}
return merged_queue;
}
和主函数
q1.merge_queues(q2);
但错误是
Non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'Queue<int>'
不知道是不是模板的问题
解决方法
这是一个使用 std::queue
的工作程序。您的自定义 Queue
类的逻辑将相同。请注意,我只检查一次队列是否为空。您检查作为循环条件,但由于您选择了 ||
,因此您不得不再次检查。最好先处理简单的部分(当两者都不为空时),然后将其余部分作为单独的任务计算出来。
分离您的关注点使您的代码更易于编写和管理。
#include <iostream>
#include <queue>
#include <random>
std::queue<int> merge(std::queue<int>& q1,std::queue<int>& q2) {
std::queue<int> merged;
while (!q1.empty() && !q2.empty()) {
merged.push(q1.front());
q1.pop();
merged.push(q2.front());
q2.pop();
}
// By this point,one of the queues is empty,we merely have to add the
// remaining elements of the other queue
std::queue<int>& remain = q1.empty() ? q2 : q1;
while (!remain.empty()) {
merged.push(remain.front());
remain.pop();
}
return merged;
}
int main() {
// Set up
std::mt19937 prng(std::random_device{}());
std::uniform_int_distribution<int> sizes(10,30);
std::queue<int> odds;
std::queue<int> evens;
int oddSize = sizes(prng);
int evenSize = sizes(prng);
// Fill odds
for (int i = 1,idx = 0; idx < oddSize; i += 2,++idx) {
odds.push(i);
}
// Fill evens
for (int i = 2,idx = 0; idx < evenSize; i += 2,++idx) {
evens.push(i);
}
std::cout << "Odd size: " << odds.size() << "\nFront: " << odds.front()
<< "\nBack: " << odds.back() << "\n\n";
std::cout << "Even size: " << evens.size() << "\nFront: " << evens.front()
<< "\nBack: " << evens.back() << "\n\n";
// Merge and print merged
auto m = merge(odds,evens);
while (!m.empty()) {
std::cout << m.front() << ' ';
m.pop();
}
std::cout << '\n';
}
输出:
Odd size: 20
Front: 1
Back: 39
Even size: 14
Front: 2
Back: 28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 31 33 35 37 39
您的合并代码看起来不错,尽管有点不稳定。该问题可能与您的 Queue
类的实现有关。这就是测试驱动开发发挥作用的地方。
您认为错误出在一处,但很可能在另一处。在您编写完 Queue
类之后,您是否对其进行了任何测试?您有一些没有意义的函数,例如 QueueEmpty()
和 QueueFull()
。怎么可能满?调用一个只打印出来的函数有什么好处?
我不知道您要使用动态数组还是链表作为 Queue
的后备存储。我想通过全面检查,您将使用动态数组。
您需要区分 .front()
& .back()
和 .pop()
。
您声称您的 Queue
是一个模板类,但您将 front
和 back
存储为 int
,为什么?