编写迭代函数来计算数学序列
Posted
技术标签:
【中文标题】编写迭代函数来计算数学序列【英文标题】:write iterative function to calculate a mathematics sequence 【发布时间】:2021-12-10 07:37:16 【问题描述】:对于家庭作业,我需要编写两个函数来计算相同的数学序列,递归和迭代版本。递归版编程成功了,但是不知道怎么实现迭代版。
(这是我第一次用C语言编程。)
递归版本:
float sequence(int n)
float x = 1.0;
if(n>=1)
float temp = sequence(n-1);
x = temp+1/temp;
return x;
如果代码有效,我必须找到 sequence(0) = 1, sequence(1) = 2, sequence(3) = 2.5, sequence(4) = 2.9,..., sequence(100) ~ 14.284066.
另外,根据我的教授的说法,代码必须足够优化(时间复杂度?)并且没有明显的语义问题(太容易发现)。
您能帮我实现迭代版本并提出任何建议吗?
所以,如果这个问题已经被问过了,对不起,请给我链接。
另外,我感谢您的宝贵时间,
真诚的。
【问题讨论】:
如果这是您第一次编写 C,那么您绝对应该退后一步,先找一些书籍或课程来学习 C 的基础知识。如果这真的是第一次写C的第一次家庭作业,那么你的老师要你在你刚出生的时候跑步,那是行不通的。 数学序列?什么数学序列? 这是一个序列:en.wikipedia.org/wiki/Sequence 在n
上编写一个循环,其中每次迭代都会计算n
的结果,前提是您之前为n-1
计算的值。与您所拥有的类似,但使用循环而不是递归。
这看起来像导致黄金比例的序列,它大约是 1.6 而不是 14.28...,正如你提到的。你确定你的程序是正确的?
【参考方案1】:
您的递归以解构方式工作,从n
开始,然后通过递归调用向后工作,直到达到基本情况。对于基本情况,它返回已知的答案,并在基本情况之上的每一层使用返回的结果来评估方程。
对于迭代,您希望从基本情况到n
进行建设性工作。在每次迭代中,当前值用于更新上一次迭代的结果。
您使用了pseudocode
标记,所以我在Ruby 中提供了它(这实际上是伪代码,但可以运行以检查答案)。你可以自己翻译成C来加强你的理解。
def recursive(n)
return 1.0 if n < 2
x = recursive(n - 1)
return x + 1 / x
end
def iterative(n)
x = 1.0
if n > 1
(n - 1).times x += 1.0 / x
end
return x
end
# Test it out
(0..10000).each |input| puts "#recursive(input)\t#iterative(input)"
我已经测试过,对于n
,两者都返回相同的答案,最多可达 10000。
【讨论】:
完美,我去咨询一下! 请注意,您不应该太快将这里的“the”答案勾选出来,好的替代答案可能会在数小时后出现。 这正是我想要的,它有效! 请注意,您不应该太快将这里的“the”答案勾选出来,好的替代答案可能会在数小时后出现。我不经常使用这个网站。 很高兴为您工作。请注意,它还减少了声明的变量数量(相对于您的初始实现)。【参考方案2】:我看出来了,显然是Fractional Chromatic Number 序列。
#include <stdio.h>
double seqrec(unsigned n)
if (n < 2) return 1;
double prev = seqrec(n - 1);
return prev + 1 / prev;
double seqiter(unsigned n)
double numerator = 1, denominator = 1;
for (unsigned k = 2; k <= n; k++)
double newnumerator = numerator*numerator + denominator*denominator;
denominator = numerator*denominator;
numerator = newnumerator;
// avoid nan, get numbers down to a reasonable level :-)
while (denominator > 2)
numerator /= 2;
denominator /= 2;
return numerator / denominator;
int main(void)
for (int k = 1; k < 49; k++)
printf("%d ==> %f, %f\n", k, seqrec(k), seqiter(k));
输出如下
1 ==> 1.000000, 1.000000 2 ==> 2.000000, 2.000000 3 ==> 2.500000, 2.500000 4 ==> 2.900000, 2.900000 5 ==> 3.244828, 3.244828 6 ==> 3.553010, 3.553010 7 ==> 3.834462、3.834462 8 ==> 4.095255、4.095255 9 ==> 4.339440, 4.339440 10 ==> 4.569884, 4.569884 11 ==> 4.788708, 4.788708 12 ==> 4.997533, 4.997533 13 ==> 5.197631, 5.197631 14 ==> 5.390027, 5.390027 15 ==> 5.575555, 5.575555 16 ==> 5.754909, 5.754909 17 ==> 5.928674、5.928674 18 ==> 6.097345, 6.097345 19 ==> 6.261351, 6.261351 20 ==> 6.421061, 6.421061 21 ==> 6.576799, 6.576799 22 ==> 6.728848, 6.728848 23 ==> 6.877462, 6.877462 24 ==> 7.022865, 7.022865 25 ==> 7.165257, 7.165257 26 ==> 7.304819, 7.304819 27 ==> 7.441715, 7.441715 28 ==> 7.576093, 7.576093 29 ==> 7.708087, 7.708087 30 ==> 7.837821, 7.837821 31 ==> 7.965407, 7.965407 32 ==> 8.090950, 8.090950 33 ==> 8.214545, 8.214545 34 ==> 8.336280, 8.336280 35 ==> 8.456238, 8.456238 36 ==> 8.574494, 8.574494 37 ==> 8.691119, 8.691119 38 ==> 8.806179, 8.806179 39 ==> 8.919735, 8.919735 40 ==> 9.031846, 9.031846 41 ==> 9.142565, 9.142565 42 ==> 9.251944, 9.251944 43 ==> 9.360029, 9.360029 44 ==> 9.466867, 9.466867 45 ==> 9.572498, 9.572498 46 ==> 9.676964, 9.676964 47 ==> 9.780302, 9.780302 48 ==> 9.882549, 9.882549【讨论】:
非常感谢您的回答,这对我的工作非常有帮助。真诚的! 你不应该调用递归两次,这会导致指数运行时间。此外,将nan
作为结果表示存在错误。
我摆脱了nan
结果和双递归调用。 nan
是因为 numerator
和 denominator
正在呈指数级快速增长。
@mxbr236 如果它帮助/解决了您的问题,请考虑接受答案
我想知道你为什么需要numerator
/denominator
,基本的递归关系非常简单。以上是关于编写迭代函数来计算数学序列的主要内容,如果未能解决你的问题,请参考以下文章