编写迭代函数来计算数学序列

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 是因为 numeratordenominator 正在呈指数级快速增长。 @mxbr236 如果它帮助/解决了您的问题,请考虑接受答案 我想知道你为什么需要numerator/denominator,基本的递归关系非常简单。

以上是关于编写迭代函数来计算数学序列的主要内容,如果未能解决你的问题,请参考以下文章

PSET 6 DNA:如何计算连续 STR 的运行次数

迭代器和可迭代协议

Python内置函数——最值与求和

在matlab里调用一个函数,怎么知道它计算过程中迭代了多少次呢

高阶函数

地图距离矩阵:如何迭代数据框中的行序列并计算距离