【问题标题】:Merge two queues in one alternately taking elements from each queue将两个队列合并为一个,交替从每个队列中获取元素
【发布时间】:2021-07-16 21:11:09
【问题描述】:

我在 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>'

不知道是不是模板的问题

【问题讨论】:

  • 您可以执行q1.merege_queues(q2) 并从merge_queues 方法中删除一个arugmet。
  • 是的,我尝试了不同的方法,但仍然出现错误。
  • 你能说出这个错误发生在哪一行吗?

标签: c++ computer-science


【解决方案1】:

这是一个使用std::queues 的工作程序。对于您的自定义 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 是一个模板类,但您将frontback 存储为ints,为什么?

【讨论】:

    猜你喜欢
    • 2010-10-26
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多