求平方根时获得精确答案(非近似)的最快算法
抱歉标题不清楚,但我不知道如何正确表述(请随意编辑),所以我将给出示例:
sqrt(108) ~ 10.39...但我希望它像这样 sqrt(108) =6*sqrt(3) 所以这意味着扩展到两个数字
这就是我的算法
i = floor(sqrt(number)) //just in case, floor returns lowest integer value :)
while (i > 0) //in given example number 108
if (number mod (i*i) == 0)
first = i //in given example first is 6
second = number / (i*i) //in given example second is 3
i = 0
i--
也许你知道更好的算法?
如果重要的话我会使用 PHP,当然我会使用适当的语法
Sorry for unclear title, but I don't know how to state it properly (feel free to edit), so I will give example:
sqrt(108) ~ 10.39... BUT I want it to be like this sqrt(108)=6*sqrt(3) so it means expanding into two numbers
So that's my algorithm
i = floor(sqrt(number)) //just in case, floor returns lowest integer value :)
while (i > 0) //in given example number 108
if (number mod (i*i) == 0)
first = i //in given example first is 6
second = number / (i*i) //in given example second is 3
i = 0
i--
Maybe you know better algorithm?
If it matters I will use PHP and of course I will use appropriate syntax
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对此没有快速算法。它要求您找到所有平方因子。这至少需要一些因式分解。
但你可以大大加快你的接近速度。首先,您只需要找到 n 的立方根以内的质因数,然后使用 确定整数的平方根是否是整数的最快方法。
接下来加快速度,从底层开始工作。每次找到质因数时,重复将 n 除以它,累加平方。当你减少 n 的大小时,就会减少你将达到的限制。这可以让您利用大多数数字可以被一些小数字整除的事实,从而快速减少剩余要分解的数字的大小,并让您更快地停止搜索。
接下来的性能改进,开始变得更聪明地知道你用哪些数字来进行试除。例如特殊情况2,则只测试奇数。您刚刚再次将算法的速度提高了一倍。
但请注意,即使有了所有这些加速,您也只是获得了更高效的强力。它仍然是蛮力,并且仍然不会很快。 (尽管它通常比您当前的想法快得多。)
这里有一些伪代码可以清楚地说明这一点。
请注意,各种+1是为了避免浮点数不精确的问题。
运行 2700 的算法的所有步骤,会发生以下情况:
There is no fast algorithm for this. It requires you to find all the square factors. This requires at least some factorizing.
But you can speed up your approach by quite a bit. For a start, you only need to find prime factors up to the cube root of n, and then test whether n itself is a perfect square using the advice from Fastest way to determine if an integer's square root is an integer.
Next speed up, work from the bottom factors up. Every time you find a prime factor, divide n by it repeatedly, accumulating out the squares. As you reduce the size of n, reduce your limit that you'll go to. This lets you take advantage of the fact that most numbers will be divisible by some small numbers, which quickly reduces the size of the number you have left to factor, and lets you cut off your search sooner.
Next performance improvement, start to become smarter about which numbers you do trial divisions by. For instance special case 2, then only test odd numbers. You've just doubled the speed of your algorithm again.
But be aware that, even with all of these speedups, you're just getting more efficient brute force. It is still brute force, and still won't be fast. (Though it will generally be much, much faster than your current idea.)
Here is some pseudocode to make this clear.
Note that the various +1s are to avoid problems with the imprecision of floating point numbers.
Running through all of the steps of the algorithm for 2700, here is what happens:
不太可能有快速的算法来解决这个问题。请参阅https://mathoverflow.net/questions/16098/complexity-of-testing-integer -square-freeness 特别是https://mathoverflow.net /questions/16098/测试复杂性-整数平方-自由度/16100#16100
It's unlikely that there is a fast algorithm for this. See https://mathoverflow.net/questions/16098/complexity-of-testing-integer-square-freeness especially https://mathoverflow.net/questions/16098/complexity-of-testing-integer-square-freeness/16100#16100