我最近写了一次计算机科学考试,他们要求我们为cos taylor系列扩展给出一个递归定义。这是系列
cos(x)= 1-x ^ 2/2! + x ^ 4/4! + x ^ 6/6! ...
并且函数签名如下所示
float cos(int n , float x)
其中,n表示用户要计算直到的序列号,x表示cos函数中x的值
我显然没有正确地回答这个问题,并且过去几天来我一直在试图找出答案,但是我碰到了砖墙
任何人都可以帮助我从某个地方开始吗?
到目前为止所有答案每次都会重新计算阶乘。我肯定不会那样做。相反,您可以编写:
float cos(int n, float x)
{
if( n > MAX )
return 1;
return 1-x*x/( (2*n-1)*2*n ) * cos(n+1, x);
}
考虑到cos返回以下内容(对点位置表示抱歉):
您可以看到这对于n> MAX,n = MAX等是正确的。容易看到符号交替和x的幂。
最后,在n = 1时,您得到0! = 1,因此调用cos(1, x)
会得到cos的泰勒展开式的第一个MAX项。
通过开发(易于查看何时只有很少的术语),您可以看到第一个公式等于以下内容:
“>
对于n> 0,用cos(n-1,x)除以先前结果的(2n-3)(2n-2),再乘以x²。您可以看到,当n = MAX + 1时此公式为1,其中n = MAX则为1-x²/((2MAX-1)2MAX)
,依此类推。
如果允许自己使用助手功能,则应将上述签名更改为float cos_helper(int n, float x, int MAX)
并这样调用:
float cos(int n, float x) { return cos_helper(1, x, n); }
编辑:将n
的含义从所评估术语的程度(至目前为止的答案)转换为术语数量(如问题及其下方内容),但仍然不会每次都重新计算总阶乘,我建议使用两个关系。
让我们简单地定义cos(0,x) = 0
和cos(1,x) = 1
,并尝试通常获得泰勒级数的n个第一项之和的cos(n,x)。
然后对于每个n> 0,我们可以从cos(n-1,x)写入cos(n,x):
cos(n,x)= cos(n-1,x)+ x 2n
/(2n)!现在为n> 1,我们尝试显示cos(n-1,x)的最后一项(因为它是最接近我们要添加的项):
cos(n,x)= cos(n-1,x)+x²/(((2n-1)2n)*(x 2n-2
/(2n-2)!)]通过将此公式与上一个公式结合起来(使其适应n-1而不是n):
cos(n,x)= cos(n-1,x)+x²/((2n-1)2n)*(cos(n-1,x)-cos(n-2,x))
我们现在有了cos(n,x)的纯递归定义,没有辅助函数,没有重新计算阶乘,泰勒分解总和中的项数为n。
但是,我必须强调以下代码将非常出色地执行:
cos(n-1,x)
的[C0现在此免责声明已经就绪,代码如下:
cos( (n-1) - 1, x)
您可以使用循环或递归,但是我建议使用循环。无论如何,如果必须使用递归,则可以使用以下代码]
就像加起来一样。
想要递归但函数参数不携带所需信息的常用技术是引入helper function
n