二分法與牛頓法

二分法與牛頓法


這裏寫圖片描述


極限思想

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

算法實現:

double getE(double n){
    double a = 1;   //a爲每一項的值
    double e = a;
    if (n==1) {
        return e;
    }
    for (double i=1; i<=n; i++) {
        a /= i;  //後一項等於前一項處以i
        e += a;  //e等於各項值相加
    }
    return e;
}

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

double getPI(double n){
    double a = sqrt(3)/3;  //a紀錄分子
    double PI = a;
    if (n==1) {
        return PI;
    }
    for (double i=1; i<=n; i++) {
        a = -a/3;     //分子按照該方式迭代
        PI += a/(2*i+1);
    }
    return 6*PI;
}

如何求√3呢?以下引出二分法和牛頓法

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述


冪運算

這裏寫圖片描述

這裏寫圖片描述

線性算法代碼

    double powLinear(double x, int n) {
        double result = 1;
        for (int i = 1; i <= n; i++) {
            result *= x;
        }
        return result;
    }
    double myPowLinear(double x, int n) {
        if (n == 0) {
            return 1;
        } else if (n == 1) {
            return x;
        } else {
            if (n > 0) {
                return powLinear(x, n);
            } else {
                return 1 / powLinear(x, -n);
            }
        }
    }

logN算法代碼

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

double plus_Pow(double x, int n) {
    double ans = 1;

    if (n==0) {
        return ans;
    }

    double temp = plus_Pow(x, n/2);  //這樣計算的話就可以只計算一次;
    if (n%2==0) {
        ans = temp*temp;   //如果這裏temp寫成plus_Pow(x, n/2);則該同樣的式子將被計算多次
    }
    else
        ans = temp*temp*x;
    return ans;
}

double myPow(double x, int n){
    if (n==0) {
        return 1;
    }
    if (n==1) {
        return x;
    }
    if (n>0) {
        return plus_Pow(x, n);
    }
    else
        return 1/plus_Pow(x, -n);  //當n爲負數時,計算相應的正數的冪函數後,取倒數

}

這裏寫圖片描述


平方根

  • 題目描述:

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

代碼實現:

double round(double r)
{
    return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
}

double mySqrt(double x){

    double start = 0;
    double end = x;

    while (true) {
        double mid = (start+end)/2;
        if (fabs(mid-x/mid)<0.00001) {  //c++中,求int型平均值用abs(); 求double型的用 fabs();
            double temp = round(mid);  //注意:c++中沒有round函數,所以需要自己實現
            if (temp==x/temp) {   // 避免9的根號爲2.9999的情況,也就是把所求的結果變爲最近的整數,看看這個整數的平方是否爲x;如果是,則返回這個整數
                return  temp;
            }
            else
                return mid;
        }
        else if (mid < (x/mid)) {
            start = mid;
        }
        else{
            end = mid;
        }
    }
}

round() 函數的實現:

這裏寫圖片描述


這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

代碼:

double myNewtonSqrt(double y){
    double ans = y;
    if (y==0||y==1) {
        return ans;
    }
    while (true) {
        if (fabs(ans-y/ans)<0.00001) {  //c++中,求int型平均值用abs(); 求double型的用 fabs();
            double temp = round(ans);  //注意:c++中沒有round函數,所以需要自己實現
            if (temp==y/temp) {   // 避免9的根號爲2.9999的情況,也就是把所求的結果變爲最近的整數,看看這個整數的平方是否爲x;如果是,則返回這個整數
                return  temp;
            }
            else
                return ans;
        }
        else{
            ans = ans - (ans*ans-y)/(2*ans);  //牛頓法遞歸求解
        }
    }
}

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

    int mySqrt(int x){
        if (x==0||x==1) {
            return x;
        }
        double ans = x;
        while (true) {
            if (fabs(ans-x/ans)<1&&(floor(ans)-x/ans)<=0) {  
                    return floor(ans);
            }
            else{
                ans = ans - (ans*ans-x)/(2*ans);  //牛頓法遞歸求解
            }
        }
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章