【问题标题】:Transforming Hermite Polynomial Recursion to a solution using std::stack使用 std::stack 将 Hermite 多项式递归转换为解决方案
【发布时间】:2021-10-09 00:06:51
【问题描述】:

Hermite 多项式由以下公式定义,其中 n>0 且 x 为实数:

我已经定义了一个使用递归的解决方案:

int hermitPolynomial(int n, int x){
    if(n == 0){
        return 1;
    }
    if (n == 1){
        return x*2;
    }
    return 2*x*hermitPolynomial(n-1,x) + 2*(n-1)*hermitPolynomial(n-2,x);
} 

如何使用堆栈将函数转换为迭代解决方案?另外,使用堆栈将递归转换为迭代函数的基础是什么?

我设法将难度较低的递归(如斐波那契)转换为迭代堆栈解决方案。

这是我尝试过的解决方案,但我没有想到一种方法来跟踪“2x”和“2(n-1)”:

int hermitPolynomialIter(int n, int x){
    std::stack<int> s;
    int result = 0;
    s.push(n);
    while(!s.empty()){
        int temp = s.top(); s.pop();
        if(temp == 1){
            result+=1;
        }
        else if(temp == 2){
            result+=2*x;
        }
        else{
            s.push(temp-1);
            s.push(temp-2);
        }
    }
    return result;
}

【问题讨论】:

  • 为什么要使用堆栈?迭代解决方案只是一个循环
  • @463035818_is_not_a_number 主要用于练习栈的使用。但也有一些语言(如 python)具有递归深度限制,因此在某些情况下迭代更好。谢谢!
  • 练习堆栈的一部分是学习何时使用它们,何时不使用它们。你把一些相对简单的东西变成了相对复杂的东西。只是说。如果这样做的全部目的是练习std::stack,您可能应该在问题中提及这一点
  • 我试了一下,但很抱歉,我真的不明白堆栈如何适合这里。您似乎想使用堆栈来跟踪前两个结果,但是循环 while(!s.empty()) 没有任何意义。在每次迭代中,您将最后两个值添加回堆栈,因此它永远不会为空
  • fwiw,最新的答案是使用堆栈作为(复杂的)方式来存储前两个结果,这就是我希望首先在您的代码中找到的内容。这是一种方法,但我的建议仍然适用:请注意,在这里使用堆栈的唯一原因是练习使用堆栈

标签: c++ algorithm recursion stack


【解决方案1】:

提示:

请注意,递归公式用两个前面的计算(即Hn-1Hn-2)表示Hn。因此,您可以只使用保存这些评估的两个变量(让H1H2)来执行它,并在您增加n 时移动它们。

循环体读取

H0= 2 * X * H1 + 2 * (N-1) * H2;
H2= H1;
H1= H0;
N++;

对于所有迭代,以下不变量将成立:H1 = Hn-1 and H2 = Hn-2

我让你了解变量H0H1H2 应该如何初始化(考虑N=2)。

【讨论】:

    【解决方案2】:

    首先,让我注意到recurrence formula

    H_n(x) = 2xH_{n-1}(x) - 2(n-1)H_{n-2}(x)
    

    (注意减号)。

    这是一个解决方案,以及计算 x=1 和 x=2 处的第一个多项式的小测试。

    #include <stack>
    #include <iostream>
    
    int hermitePolynomial(int n, int x)
    {
      std::stack<int> s;
      if (n == 0)
        {
          return 1;
        }
      else if (n == 1)
        {
          return 2 * x;
        }
      else
        {
          s.push(1);
          s.push(2 * x);
          for (int k = 2; k <= n; ++k)
        {
          auto hermite_k_minus_1 = s.top();
          s.pop();
          auto hermite_k_minus_2 = s.top();
          s.pop();
          auto hermite_k = 2 * x * hermite_k_minus_1 - 2 * (k - 1) * hermite_k_minus_2;
          s.push(hermite_k_minus_1);
          s.push(hermite_k);
        }
          return s.top();
        }
    }
    
    int main()
    {
      for (const int x : { 1, 2 })
        {
          std::cout << "Polynomials at x = " << x << std::endl;
          for (int i = 0; i < 5; ++i)
        std::cout << "H_" << i << "(" << x << ") = " << hermitePolynomial(i, x) << std::endl;
        }
    
      return 0;
    }
    

    Live on Coliru

    主要思想是您在循环上迭代以计算第 k 个多项式,并将最后 2 个多项式保留在堆栈中,即索引 k-1 和 k-2 的多项式。

    【讨论】:

      猜你喜欢
      • 2020-06-07
      • 1970-01-01
      • 2014-08-20
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 2019-06-26
      • 1970-01-01
      • 2013-03-14
      相关资源
      最近更新 更多