【问题标题】:Program to calculate square root c++计算平方根的程序c ++
【发布时间】:2020-03-17 11:12:00
【问题描述】:

我正在制作一个 C++ 程序来计算数字的平方根。该程序不使用内置的“sqrt”数学运算。有两个变量,一个是用户将输入的数字,另一个是该数字的平方根。这个程序不太好用,我相信有更好的方法来做到这一点:

这是我的完整代码:

#include <iostream>
using namespace std;

int main(){
  int squareroot = 0;
  int number;

  cout << "enter a number sp that i can calculate its squareroot" << endl;

  cin >> number;

  while (squareroot * squareroot != number){

      squareroot+=0.1;

}
cout << "the square root is" << squareroot << endl;
return 0;
 }

我知道一定有更好的方法。请帮忙。通过谷歌浏览但不了解那里的复杂程序,因为我还是一个初学者。

提前致谢。

【问题讨论】:

  • 这不是真正的编程问题,而是数学问题。有几种(高效和低效)算法。首先你应该选择一个并深入研究它,直到你详细理解它,然后尝试实现它。
  • 首先,您需要知道未初始化的局部变量(如您的 squarertoot 变量)具有 indeterminate 值,使用它们会导致 undefined行为。其次,您将 squareroot 声明为 整数 变量,您不能添加浮点值并期望它正常工作。
  • 对不起,我弄错了,刚刚编辑了 squareroot = 1;

标签: c++


【解决方案1】:

下面对整数平方根的计算给出解释:

在数论中,正数的整数平方根 整数 n 是减去最大整数的正整数 m 大于或等于 n 的平方根

您开始的方法很好,但需要进行多次修正才能使其发挥作用:

  1. 您正在使用 int,您想将 1 加到 squareroot 而不是 0.1

  2. 您想在squareroot * squareroot 等于或大于number 时停止计算。想想这个数字是 26 的情况,你没有一个整数可以乘以 26。

  3. 在数字等于26的情况下,你想返回5还是6?在您的while 循环之后,squareroot 的值将为 6,因此您可能希望将其反转为 5(如果 squareroot * squarerootnumber 不同)

下面的例子:

#include <iostream>
using namespace std;

int main(){
  int squareroot = 0;
  int number;

  cout << "enter a number sp that i can calculate its squareroot" << endl;

  cin >> number;

  while (squareroot * squareroot < number){
      squareroot+=1;
  }

  if (squareroot * squareroot != number) --squareroot;

  cout << "the square root is" << squareroot << endl;
  return 0;
}

下面是一种使用二分搜索原理计算平方根的更高效、更优雅的方法。 O(log(n))

int mySqrt(int x) {
    if (x==0) return 0;
    int left = 1;
    int right = x/2 + 1;
    int res;

    while (left <= right) {
        int mid = left + ((right-left)/2);
        if (mid<=x/mid){
            left = mid+1;
            res=mid;
        }
        else {
            right=mid-1;
        }
    }

    return res;
}

【讨论】:

  • 我相信仅仅给 OP 一个解决方案并不能真正帮助他们。也许更好的方法是指出他们的代码为什么不起作用,然后指出他们如何改变它的正确方向?
  • 但结果不一定是整数。
  • @user1095108 你说得对,上面的解释只适用于整数平方根计算
  • 感谢回复?
  • @Aryan.C 不客气!如果有帮助,请接受答案。谢谢
【解决方案2】:

此函数使用嵌套间隔(未经测试),您可以定义准确性:

#include <math.h>
#include <stdio.h>

double mySqrt(double r) {
  double l=0, m;
  do {
     m = (l+r)/2;
     if (m*m<2) {
        l = m;
     } else {
        r = m;
     }
  } 
  while(fabs(m*m-2) > 1e-10);      
  return m;
}

https://en.wikipedia.org/wiki/Nested_intervals

【讨论】:

  • 我相信仅仅给 OP 一个解决方案并不能真正帮助他们。也许更好的方法是指出他们的代码为什么不起作用,然后指出他们如何改变它的正确方向?
  • 正如所写,这仅输出 1.41421,即sqrt(2)。如果您将(m*m&lt;2)(m*m-2) 更改为不卡在2 上,而是使用r 和您的原始输入来检查增量,这几乎是一种二分搜索。
【解决方案3】:

如果 A 不是一个完美的平方,这个函数将计算平方根的底。这个函数基本上使用二进制搜索。你事先知道的两件事是一个数字的平方根将小于或等于那个数字,它会大于或等于 1。因此我们可以在该范围内应用二分搜索。以下是我的实现。如果您不了解代码中的任何内容,请告诉我。希望对您有所帮助。

int sqrt(int A) {
    if(A<1)return 0;
    if(A==1)return 1;

    unsigned long long start,end,mid,i,val,lval;
    start = 1;
    end = A;
    while(start<=end){
        mid = start+(end-start)/2;
        val = mid*mid;
        lval = (mid-1)*(mid-1);

        if(val == A)return mid;     
        else if(A>lval && A<val) return mid-1;
        else if(val > A)end = mid;
        else if(val < A)start = mid+1;
    }
}

【讨论】:

  • 我相信仅仅给 OP 一个解决方案并不能真正帮助他们。也许更好的方法是指出他们的代码为什么不起作用,然后指出他们如何改变它的正确方向?
  • 是的,你是绝对正确的,但问题是要求可能的更好方法,这就是为什么建议更好的方法。我认为了解不同的方法没有害处。也许我不应该发布代码只是建议方法.
【解决方案4】:

您的代码的问题在于,它仅在数字的平方根正好是 N*0.1 时才有效,其中 N 是一个整数,这意味着如果答案是 1.4142 而不是 1.400000000,那么您的代码将失败。有更好的方法,但它们都比较复杂,并且使用数值分析来近似答案,其中最简单的方法是 Newton-Raphson 方法。

你可以使用下面的函数,这个函数使用Newton-Raphson方法来寻找根,如果你需要更多关于Newton-Raphson方法的信息,查看thiswikipedia文章。如果您需要更好的准确度 - 但更差的性能 - 您可以将“0.001”减少到您的喜好,或者如果您想要更好的性能但降低准确度,可以增加它。

float mysqrt(float num)   {  
    float x = 1;

    while(abs(x*x - num) >= 0.001 )
        x = ((num/x) + x) / 2;

    return x;

}  

如果你不想导入math.h,你可以自己写abs()

float abs(float f) {
    if(f < 0)
        f = -1*f;
    return f;
}

【讨论】:

    【解决方案5】:

    一个数字的平方根,假设该数字是一个完美的平方。

    复杂度是log(n)

    /**
     * Calculate square root if the given number is a perfect square.
     * 
     * Approach: Sum of n odd numbers is equals to the square root of n*n, given 
     * that n is a perfect square.
     *
     * @param number
     * @return squareRoot
     */
    public static int calculateSquareRoot(int number) {
    
        int sum=1;
        int count =1;
        int squareRoot=1;
        while(sum<number) {
            count+=2;
            sum+=count;
            squareRoot++;
        }
        return squareRoot;
    }
    

    【讨论】:

      【解决方案6】:
      #include <iostream>
      using namespace std;
      int main()
      {
          double x = 1, average, s, r;
          cout << "Squareroot a Number: ";
          cin >> s;
          r = s * 2;
          for ( ; ; ) //for ; ; ; is to run the code forever until it breaks
          {
              average = (x + s / x) / 2;
              if (x == average)
              {
                  cout << "Answer is : " << average << endl;
                  return 0;
              }
              x = average;
          }
      }
      

      你可以试试我的代码 :D 我在这里使用的方法是巴比伦平方根方法 你可以在这里找到它https://en.wikipedia.org/wiki/Methods_of_computing_square_roots

      【讨论】:

        猜你喜欢
        • 2021-01-04
        • 2021-08-03
        • 2017-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多