【问题标题】:Binary search to find nth root of a number二进制搜索以找到数字的第 n 个根
【发布时间】:2018-02-27 01:23:30
【问题描述】:

我尝试使用二分搜索实现一个函数来解决以下问题:

实现一个计算一个数的第 n 个根的函数 root。该函数接受一个非负数 x 和一个正整数 n,并在 0.001 的误差范围内返回 x 的第 n 个正根(即假设实根为 y,则误差为:|y-root(x, n)| 并且必须满足 |y-root(x,n)|

我的代码:

double binarysearch(double left,double right, double x, int n){
 while(left<right){
  double mid = left + (right-left)/2;
  double answer = pow(mid,n);
   if(fabs(answer - x ) <= DELTA)
    return mid;
  else if(answer > x )
      right = mid - DELTA;
  else 
     left = mid + DELTA;
 }
  return -1;
}

这达到了左>右的条件并返回-1。

有没有办法使用二分搜索来实现这一点?

【问题讨论】:

  • 尝试调试,例如通过在每一步打印变量的值。
  • 请注意,二分搜索是错误的术语。您不是在列表中搜索特定值。您应该在 x^(-n) 的 DELTA 中搜索 any y,即 y^n - x = 0, fabs(y - x^(-n) 的根 y 附近的数字) 二等分。如果您将其用作搜索词,您将获得大量点击和许多正确实现的示例。 @MattTimmermans 的答案对于这个特定问题得到了相同的答案,但二分算法将适用于查找非常大的函数 f(x)=0 类的根 x。
  • try/port this How to get a square root for 32 bit input in one clock cycle only? 它使用二进制搜索和高度优化的方法(不需要乘法)还有很多其他类似的方法,如How approximation search works 那里的另一个答案描述了此代码使用的二分法...然后也有近似方法。另请参阅Power by squaring for negative exponents 了解完整的 bin 搜索与平方的内容

标签: algorithm binary-search square-root


【解决方案1】:

您的函数中断是因为 (mid-DELTA)^nmid^n 之间的差异通常大于 DELTA。 p>

使用双精度进行二进制搜索可能会很棘手,根据您真正想要的结果,有多种方法可以做到这一点。在这种情况下,您被要求在实际根的 0.001 范围内给出答案。 要求您的 answer^nx 的 0.001 以内。

这表明这样的实现:

double binarysearch(double x, int n)
{
    double lo = 0.0;
    double hi = x;
    while(hi-lo >= 0.0019)
    {
        double test = lo+(hi-lo)*0.5;
        if (test == low || test == hi)
        {
           //I couldn't bear to leave this out.  Sometimes there are no
           //double values between lo and hi.  This will be pretty much
           //as close as we can get.  Break here to avoid an infinite loop
           break;
        }
        if (pow(test,n) < x)
        {
            lo = test;
        }
        else
        {
            hi = test;
        }
    }
    //cut the final range in half.  It's less than
    //0.0019 in size, so every number in the range, which includes
    //the root, is less than 0.001 away from this
    return lo+(hi-lo)*0.5;
}

请注意,不可能返回“未找到”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 2023-03-24
    • 2018-06-20
    相关资源
    最近更新 更多