2015-10-23 356 views
0

我正在製作一個C++程序來計算數字的平方根。該程序不使用內置的「sqrt」數學運算。有兩個變量,一個用於用戶輸入的數字,另一個用於該數字的平方根。這個程序不工作非常好,我相信有一個更好的方式來做到這一點:程序來計算平方根C++

這裏是我的全碼:

#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; 
} 

我知道必須有一個更好的辦法。請幫助。通過谷歌瀏覽,但不瞭解那裏的複雜程序,因爲我仍然是一個初學者。

在此先感謝。

+9

這是不是一個真正的編程問題,而是一個數學問題。有幾種(高效率和低效率)算法。首先,你應該選擇一個並深入研究,直到你詳細理解它,然後嘗試實現它。 – CompuChip

+3

首先,你需要知道未初始化的局部變量(比如你的'squarertoot'變量)有一個* indeterminate *值,並且使用它們會導致* undefined behavior *。其次,你將'squareroot'聲明爲一個* integer *變量,你不能添加一個浮點值並且期望它工作正常。 –

+0

取代!=與< – secolive

回答

2

下面給出解釋爲整數平方根計算:

在數論,正 整數n的整數平方根是正整數米這是最大的整數小於 或等於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(日誌(n))的

int mySqrt(int x) { 
    if (x==0) return 0; 
    int left = 1; 
    int right = x; 
    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; 
} 
+5

我相信只給OP一個解決方案並不能真正幫助他們。也許更好的方法是指出爲什麼他們的代碼不工作,然後指出他們如何改變它的正確方向? – Default

+1

但結果不一定是整數。 – user1095108

+0

@ user1095108你是對的上述解釋只適用於整數平方根計算 –

1

該函數將計算平方根的地板如果A是不是一個完美的square.This功能基本上都採用你知道二進制search.Two事情事先是,一些平方根將小於或等於該數字,它將大於或等於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; 
    } 
} 
+3

我相信只給OP一個解決方案並不能真正幫助他們。也許更好的方法是指出爲什麼他們的代碼不工作,然後指出他們如何改變它的正確方向? – Default

+0

是的你是絕對正確的,但問題是要求可能更好的方式,這就是爲什麼建議更好的方式。我認爲不知道不同的方法沒有傷害。也許我不應該發佈代碼只是建議的方法。 – Khatri

1

此功能使用區間套(未經測試),你可以定義精度:

#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

+5

我相信只給OP一個解決方案並不能真正幫助他們。也許更好的方法是指出爲什麼他們的代碼不工作,然後指出他們如何改變它的正確方向? – Default

1

與您的代碼的問題是,它只能如果平方根的數字恰好是N * 0.1,其中N是一個整數,這意味着如果答案是1.4142而不是1.400000000,那麼您的代碼就會失敗。有更好的方法,但它們都更復雜,並使用數值分析來近似答案,其中最簡單的就是牛頓 - 拉夫遜方法。

您可以使用下面的函數,該函數使用Newton-Raphson方法找到根,如果您需要更多關於Newton-Raphson方法的信息,請查看this維基百科文章。如果你需要更好的準確性 - 但性能更差 - 你可以減少'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; 
}