递归:使用堆栈

时间:2016-03-27 19:14:57

标签: c++ arrays stack

我需要一些关于如何解决这个问题的一般性建议,而不会过度复杂化:

  

使用数组(而不是链表),编写StackType类的成员函数,在引用页面时更新堆栈。假设一个堆栈可以容纳5个值,而下一个引用的页面是7,那么:

     
      
  • 该函数在堆栈中搜索第7页
  •   
  • 如果找到7,则将其从堆栈中删除并将其放在顶部
  •   
  • 如果在列表中找不到7,则堆栈中引用的最后一页被删除,堆栈顶部有7个位置
  •   
     

使用以下驱动程序功能:

void updateRecursive(StackType<Type>& s, Type t);
     

调用递归函数

bool updateRecursiveDo(StackType<Type>& s, Type t);

到目前为止我所做的工作只包括相关功能:

  1. 我已经使用LRU算法的概念来理解这里要问的内容。

  2. 据我所知,我真正拥有的唯一工具是push和pop。

  3. RE:驱动程序功能概念,我一直都知道这是我的main()程序。即调用该函数的程序通常在测试的情况下完成,但基于他们提供给我的内容,我在教科书中查找了这个细节,发现公共驱动函数将用于调用私有递归函数保持不。将公共职能中的参数降到最低。

    class StackType {
    public: 
        void updateRecursive(StackType<Type>& s, Type t);
    private:
        bool updateRecursiveDo(StackType<Type>& s, Type t);
    }
    
    template <class Type>
    bool StackType<Type>::updateRecursiveDo(StackType<Type>& s, Type t) {
        if (isEmptyStack())
            return 0;
        else if(s.top() == t) {
            return 1;
        }
        else {
            s.pop();
            updateRecursiveDo(s,t);
        }
    }
    
    template <class Type>
    void StackType<Type>::updateRecursive(StackType<Type>& s, Type t) {
        updateRecursiveDo(s,t);
    }
    

    所以这很棒,我在main中调用函数如下,我已经搜索了7并找到了它:

    firstStack.updateRecursive(firstStack, 7);
    

    现在我正在做的是过度思考如何将数字替换回堆栈:

    1. 将我弹出的每个项目存储到一个数组中并遍历每个项目,然后在每个实例中将它们推回到堆栈中

    2. 手动将物品推回到堆叠中,但如果列表中没有7,则这不会真正起作用

    3. 我不确定当堆栈是数组时是否有更简单的方法来处理搜索和替换?

2 个答案:

答案 0 :(得分:3)

几个要点:

  1. 我认为updateRecursiveDo()没有任何理由退回任何内容,无论是bool还是其他任何内容。在我阅读您的问题时,updateRecursiveDo()的目的实际上是从堆栈中删除t(如果存在)。它是否存在,并且此函数是否删除它,在那时不再重要,因为要完成的唯一剩余步骤是将t值推到重建堆栈的顶部。
  2. 无论是否在堆栈中找到t,都会发生这一步骤,因此返回bool指标无关紧要。

    此外,您的实施无法在第三种情况下返回bool值,因此无论如何这都不会起作用。

    1. 您的updateRecursiveDo()版本无法正确执行此操作。让我们explain what your function does to your rubber duck

      • 如果筹码是空的,请不要做任何事情。

      • 如果堆栈顶部的值为t,请不要做任何事情。

      • 否则从堆栈顶部删除值,然后重试。

    2. 为此,你的橡皮鸭会问下面的逻辑问题:&#34;为什么你要删除堆栈上的所有内容,直到你得到值t,这是你想要做的? &#34;

      当然不是,根据您提出的问题的描述。我对你问题中三个要点的解释是,只应从堆栈中删除值t,而不是值t和堆栈末尾之间的每个值。如果它不包含值t,那么它可能是整个堆栈!

      现在,您如何尝试向您的橡皮鸭解释以下内容:

      • 如果堆栈为空,则不执行任何操作。

      • 从堆栈顶部删除值。

      • 如果值为t,则不执行任何操作。

      • 递归调用自身,当递归调用返回时,将值推回到当前堆栈的顶部。

      翻译成代码,这将是:

      template <class Type>
      void StackType<Type>::updateRecursiveDo(StackType<Type>& s, Type t)
      {
          if (isEmptyStack())    
              return;
      
          auto v=s.top();
      
          if (v == t)
              return;
      
          updateRecursiveDo(s, t);
      
          s.push(v);
          return;
      }
      
      template <class Type>
      void StackType<Type>::updateRecursive(StackType<Type>& s, Type t)
      {
          updateRecursiveDo(s, t);
          s.push(t);
      }
      

答案 1 :(得分:1)

updateRecursiveDo()视为从堆栈中删除元素的方法。如果找不到该元素,请删除最后一个元素。

退出后,将t推到顶部。

你不是替换t而是删除它,然后再添加它。

使用每个递归框架将弹出值临时存储在内部变量中,即:

伪代码:

updateRecursiveDo(stackt stack, page t){
   x=stack.pop();
   if (x==t) return;
   if (stack.empty()) return;
   updateRecursiveDo(stack,t);
   stack.push(x);
 }