从任意正数计算n次方根的算法



我遇到了一个有趣的难题:确实,给出了数字a和正整数n。 在不使用库的情况下计算数字的第n个根。

输入数据:数字a为实数,非负数,不超过1000,以6个小数位的精度指定。 数字n是自然数,不超过10。
输出:程序应输出一个数字:问题的答案,精度至少为小数点后5位。

自然,用铅笔在草稿中解决它,然后在编辑器中绘制它并尝试对其进行编译很有趣。 不使用谷歌搜索,使用技巧,甚至更多。 如果您是第一次决定,请首先尝试编写程序以查找通常的平方根。 如果发现任务很困难,则解决的方法几乎相同,但更为简单。 这样,您的恐惧就会消失,并且会出现某种粗略的理解。

因此,对于初学者,我将给出一个示例,说明如何不使用库函数而计算平方根。 顺序迭代算法。 即使大量,它也收敛得很快。

/* Calculating the square root by iterations */ #include <stdio.h> int main(void) { double num = 570.15; double root = num / 2; double eps = 0.01; int iter = 0; while( root - num / root > eps ){ iter++; root = 0.5 * (root + num / root); printf("Iteration: %d : root = %f\n", iter, root); } printf("root = %f", root); return 0; } 

您可以在此处运行代码: CLICK

该算法的对数复杂度? 还是另一个? :)

现在,您可以继续执行该任务的复杂版本。 在这种情况下,解决方案更加通用。

 #include <stdio.h> double mabs(double x){ return (x < 0)? -x : x; } int main(void) { double num = 8; int rootDegree = 3; printf(",     = %f\n", num); printf("  n = %d\n", rootDegree); double eps = 0.00001; //  double root = num / rootDegree; //   double rn = num; //    int countiter = 0; //  while(mabs(root - rn) >= eps){ rn = num; for(int i = 1; i < rootDegree; i++){ rn = rn / root; } root = 0.5 * ( rn + root); countiter++; } printf("root = %f\n", root); printf("  = %i\n", countiter); return 0; } 

您可以在此处运行代码: CLICK

在此解决方案中,我使用相对较好的初始近似值的想法。 然后,顺序除法是第n次方根的第二次近似。 接下来,通过平均两个当前的近似值来考虑一个新的近似值。 一致地,该算法收敛到具有预定误差的期望根。 这有点像简单的迭代方法。

这是第一个写在膝盖上的工作算法。 我们仍然需要反思加速的复杂性和可能性。 顺便说一句,您认为该算法可以实现哪些加速功能?

我觉得会有一个问题:“如果一切都在一百年前在图书馆中实现的话,为什么要这样做呢?!”

答:就个人而言,我一直喜欢考虑标准库中已经实现的算法。 尝试自己开发它们(好吧,或者开发某种缓慢移动的模仿并失败)。 它可以很好地训练大脑。 因此,我认为“重新发明轮子”非常有用。 始终使用一切就绪而对内部结构一无所知,这绝对是有害的。

Source: https://habr.com/ru/post/zh-CN469735/


All Articles