【问题标题】:Compare a Queue and a Stack's content比较队列和堆栈的内容
【发布时间】:2013-02-17 02:09:15
【问题描述】:

假设我们在 c++ 中,使用 STL 堆栈和队列

    Stack:      [1 2 3 4 5] <=>
    Queue:   => [5 4 3 2 1] =>

递归检查数据条目在内容和顺序方面是否相同的最优雅的方法是什么?假设上面显示的堆栈和队列具有相同的数据和相同的顺序。

我在概念上无法理解要做什么,因为数据 pop() 的顺序相反。

【问题讨论】:

  • Whathaveyoutried?为什么需要递归检查?
  • 我无法从概念上设想一种方法来做到这一点,所以我没有尝试过任何事情。但是,我确实突然想到,我可以根据 STL 队列查看队列的前后。我认为这会有所帮助。
  • 你确定这不是for a class?特别是因为它似乎是在同一时间。这可能被认为是作弊

标签: c++ recursion stack queue equality


【解决方案1】:

你可能不会同时弹出它们,你可以尝试弹出一个(使用记录它的东西)ADT(不要弹出队列,弹出堆栈),然后到基数(size==1),你比较并做了一些改变到队列中,然后返回。然后在每次递归调用后对记录器和当前队列的前面做一些事情,你会找到答案。

【讨论】:

    【解决方案2】:

    如果通过递归,您并不是指递归函数调用,而只是循环,那么这里有一个答案。该函数首先检查堆栈和队列的大小是否相同。如果它们的大小不同,则函数返回 false。该函数有一个本地堆栈对象,该对象获取堆栈参数的元素,以便以与传入的堆栈参数相反的顺序弹出。然后循环检查堆栈和队列的每个前/顶部元素是否相等。如果相等,则循环继续到下一次迭代。如果不相等,则函数返回 false。如果循环结束但没有返回 false,则函数返回 true。

    #include <iostream>
    #include <stack>
    #include <queue>
    using namespace std;
    
    bool check(stack<int> stackPar, queue<int> queuePar)
    {
    
        if (stackPar.size() != queuePar.size())
        {
            return false;
        }
    
        stack<int> reverseStack;
    
        for (int i = 0, initialSize = stackPar.size(); i < initialSize; ++i)
        {
            reverseStack.push(stackPar.top());
            stackPar.pop();
        }
    
        for (int i = 0; i < reverseStack.size(); ++i)
        {
            if (reverseStack.top() == queuePar.front())
            {
                reverseStack.pop();
                queuePar.pop();
            }
            else
            {
                return false;
            }
        }
        return true;
    }
    
    int main()
    {
        stack<int> myStack;
        queue<int> myQueue;
    
        for(int i = 1; i <= 5; ++i)
        {
            myStack.push(i);
            myQueue.push(i);
        }
    
        cout << "Stack and queue are ";
        cout << ( check(myStack, myQueue) ? "equal." : "not equal." ) << endl;
        return 0;
    }
    

    【讨论】:

    • 这行得通,但副本很多。根据容器的实际大小,这可能是个问题。
    【解决方案3】:

    不需要递归,这将是对资源的无用浪费。也无需更改您的queuestack(换句话说,这甚至适用于const)。

    假设您的std::stackstd::queue 都在内部使用相同类型的底层容器(如果您使用默认值,则应该是std::dequeue),那么您可以访问受保护的成员c(您的真实容器) queuestack 并使用运算符 == 比较它们:

    #include <iostream>
    #include <queue>
    #include <stack>
    
    template<typename Adapter>
    typename Adapter::container_type const& getContainer(const Adapter& adapter) {
      struct AccessProtected : private Adapter {
        static typename Adapter::container_type const& getContainer(const Adapter& adapter) { return adapter.*&AccessProtected::c; }
      };
      return AccessProtected::getContainer(adapter);
    }
    
    int main() {
      std::queue<int> queue;
      std::stack<int> stack;
      for (int i = 0; i < 10; ++i) {
        queue.push(i);
        stack.push(i);
      }
      std::cout << (getContainer(queue) == getContainer(stack) ? "equal" : "not equal") << std::endl;
      return 0;
    }
    

    现在,如果您使用不同的容器类型作为queuestack 的底层实现,您仍然可以使用相同的getContainer() 技术来获取按相同顺序排序的容器:queue::push()stack::push() 调用底层容器的push_back() 方法,只有当您pop()(和类似操作)时,stack 才会发生反转。由于这些底层容器的顺序相同,因此您可以更轻松地进行比较(留给读者作为练习;))。

    学分:我懒得重新实现受保护的成员访问器,所以我无耻地复制和修改了this one

    【讨论】:

      【解决方案4】:

      一个部分递归的解决方案是递归地从辅助堆栈中弹出队列中的所有元素,然后检查辅助堆栈和原始堆栈是否相同。这种检查也可以递归完成。

      【讨论】:

      • 确实如此;似乎认为有一种方法可以在不创建新队列或堆栈的情况下做到这一点。
      猜你喜欢
      • 1970-01-01
      • 2013-09-18
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 2015-11-16
      • 2019-03-07
      • 2021-04-29
      相关资源
      最近更新 更多