【问题标题】:For each member of a sequence, determine if it is a perfect square对于序列的每个成员,确定它是否是一个完美的正方形
【发布时间】:2015-07-05 08:22:28
【问题描述】:

我要问的不是this very popular question 的重复。对于随机选择的输入,可以进行一些快速测试,如果它们未能说出“不是平方”,则必须进行平方根的计算(我自己也尝试过 solution)。

当要测试的数字来自一个简单的序列时,情况会有所不同,因为可以使用前一个(近似)平方根。对于微不足道的序列,它也是微不足道的,例如,

long sqrt = 1;
for (long i=1; i<limit; ++i) {
   if (sqrt*sqrt == i) {
       handleSquare(i);
       ++sqrt;
   }
}

我的问题是对于更复杂的序列可以做什么

x[i] = start + i*i;

x[i] = start - i*i*i;

我正在考虑牛顿的方法,但我不知道如何使其快速(因为除法是一项非常昂贵的操作)。

【问题讨论】:

  • 我认为您的“琐碎”示例有点琐碎。从这个角度想:一个完全平方数的平方根是有理数;也就是说,数字没有小数部分。
  • @Makoto 对,这太微不足道了,因为每个人都会转而循环 sqrt。但是忘记它,这个想法是在迭代之间保留一些信息会有所帮助。

标签: java math optimization perfect-square


【解决方案1】:

您希望将您的算法应用于什么样的序列?以下是当 x[i] 发散但不会太快时应该可以很好地工作的解决方案。

例如如果

x[i] = a*i^p + o(i^p)

如果我足够大,那么你将拥有

x[i+1]-x[i] ~ p * a * i^{p-1}.

如果 y[i] 表示最大整数,使得

y[i]^2 <= x[i]

那么你有

y[i] ~ sqrt(a) i^{p/2} 

y[i+1]-y[i] ~ 1/(2 y[i]) * (x[i+1]-x[i]) ~ p/2 * sqrt(a) i^{p/2-1}

因此,您可以将此作为 y[i+1] 的猜测值,然后更新为正确的值,这样可以节省一些迭代次数。

一般来说,你总是可以使用公式

y[i+1]-y[i] ~ 1/(2 y[i]) * (x[i+1]-x[i])

作为一种猜测,但这只有在 x[i+1]-x[i] 相对于 y[i]^2 较小时才有用——即相对于 x[i]。使用

的(精确)二阶扩展对公式进行一些改进可能也是值得的
y[i+1]^2 = y[i]^2 + 2y[i](y[i+1]-y[i]) + (y[i+1]-y[i])^2

为了提高对y[i+1]的猜测。

请注意,如果当 i 很大时 x[i] 保持有界或 x 以指数速度快速发散,则此方法将无法正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-06
    • 2016-07-03
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多