求立方根算法--个人对立方根算法的穷举和优化

在hpe实训中心学习,遇到了求立方根的题目,在此做一下算法笔记,

分析过程:

数n的立方根就是n=i*i**i;所以我们会优先想到一下方法.

    static double g32(double n){ //简易版
        double i = 0, k = 0.0005f;
        if (n < 0) {    //输入负数判断
            k /= -1;
        }
        do{
            i+=k;
        }while(abs(i*i*i)<abs(n)); //abs为自己写的求绝对值方法
        return i;
    }

可以看出此方法的求解精度为0.001;且当输入数据过大时效率堪忧,所以就有了以下优化

    static double g33(double n){    //优化2
        double i = 0, k = 5f;
        if (n < 0) {
            k /= -1;
        }for (int t = 0; t < 15; t++) {//精度到小数点后15位
            do {
                i += k;  //开始时每次加5快速逼近正确值
            } while (abs(i * i * i) < abs(n));  //当i^3>=n时退出
            i-=k;k /= 9.2;  //i还原到退出前的值,k缩小,进入下一次逼近
        } 
        return i;
    }

此方法可以快速求得立方根,输入数值n不太大时使用,当n太大在逼近过程中i^3与(i+k)^3差距太大,循环次数剧增,进入死循环状态.在我电脑上当n=9999999999 (10个9)时就会进入死循环

所以想到一种解决方法,设置一循环次数计数器w,使k值随循环次数增加而增加,在一定程度上解决死循环问题.下面是代码

    static double g34(double n){    //最终优化
        double i = 0, k = 5f;
        if (n < 0) {
            k /= -1;
        }
        int w=0;
        for (int t = 0; t < 15; t++) {
            do {
                i += k;
                k=k+w*k/50000;
                w++;  //循环计数器
            } while (abs(i * i * i) < abs(n));
            i-=k;k /= 9.5;
        }
        System.out.println(w);
        return i;
    }

更改后n等于20个9也不会死循环.

最后附上所有程序代码.

package com.gfuzan.test;

import java.util.Scanner;

public class Test {

    /**
     * 开发: GFuZan
     * 时间: 2017.08.08
     * 功能: 立方根
     */
    public static void main(String[] args) {
        System.out.print("请输入一个数: ");
        Scanner sc = new Scanner(System.in);
        double n = sc.nextDouble();
        sc.close();
        System.out.println("Math:    \t"+ Math.pow(n, 1.0/3));
        System.out.println("My简易版:  \t"+g32(n));
        System.out.println("My优化2:  \t"+g33(n));
        System.out.println("My最终优化:\t"+g34(n)); 

    }

    static double g32(double n){ //简易版
        double i = 0, k = 0.0005f;
        if (n < 0) {
            k /= -1;
        }
        do{
            i+=k;
        }while(abs(i*i*i)<abs(n));
        return i;
    }
    static double g34(double n){    //最终优化
        double i = 0, k = 5f;
        if (n < 0) {
            k /= -1;
        }
        int w=0;
        for (int t = 0; t < 15; t++) {
            do {
                i += k;
                k=k+w*k/50000;
                w++;
            } while (abs(i * i * i) < abs(n));
            i-=k;k /= 9.5;
        }
        return i;
    }
    static double g33(double n){    //优化2
        double i = 0, k = 5f;
        if (n < 0) {
            k /= -1;
        }
        for (int t = 0; t < 15; t++) {
            do {
                i += k;
            } while (abs(i * i * i) < abs(n));
            i-=k;k /= 9.2;
        }
        return i;
    }
    static double abs(double f) {
        if (f < 0) {
            return 0 - f;
        }
        return f;
    }
}

运行结果

时间: 2024-10-29 22:50:18

求立方根算法--个人对立方根算法的穷举和优化的相关文章

【算法学习笔记】49.暴力穷举 BFS 剪枝 SJTU OJ 1357 相邻方案

相邻方案 Description 有一个5*5的矩阵,每个元素只可能是H或者J. 我们现在需要选择7个相邻的格子使得H的数量小于J的数量.其中,拥有公共边的两个格子可以被称为相邻的格子. 对于任意一种输入的5*5矩阵,请输出满足上述条件的方案总数. Input Format 共5行,表示矩阵情况.(每一个元素只可能是H或J) Output Format 一个整数N,代表不相同方案的总数. Input Sample HHHHH JHJHJ HHHHH HJHHJ HHHHH Output Samp

算法应用:用递归结构实现穷举服务器文件

1.实验前言:    现在的我已经习惯把文件保存在互联网上,但是当我想分享文件给伙伴们时,总是感到途径很少或者分享效率很低,如果我可以设计一种动态列表服务器文件,并允许伙伴们通过展开节点的形式浏览服务器资源,这将是多么快捷的途径. 2.实验环境    PHP运行环境    HTML , JS 节点显示模板 3.算法分析    对于服务器文件的遍历,我采用了递归函数的方式,在当前目录寻找子目录,把子目录的路径作为参数传入新的遍历层里,通过这种递归的思想既可以遍历服务器文件又可以根据文件夹作为层次的

快速开平方根算法

人们很早就在Quake3源代码中发现了类似如下的C代码,它可以快速的求1/sqrt(x),在3D图形向量计算方面应用很广 float invSqrt(float x) { float xhalf = 0.5 * x; int i = *(int*)&x; // get bits for floating value i = 0x5f3759df - (i >> 1); // gives initial guess x = *(float*)&i; // convert bits

求有向图的强连通分量的算法

下面是求有向图的强连通分量的算法的代码: import java.util.Scanner; class Qiufenliang//定义求强连通分量的类 { String lu="";//定义的一个字符型变量,记录强连通分量的路径 public static int s=0; public void qiu(int a[][],int l)//定义函数,参数a为二维数组,参数l为数组的维数 { int t=0;//定义int型变量,进行数量的统计 for(int i=1;i<l;

谈谈&quot;求线段交点&quot;的几种算法(js实现,完整版)

"求线段交点"是一种非常基础的几何计算, 在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法总结一下, 希望对大家有所帮助. 本文讲的内容都很初级, 主要是面向和我一样的初学者, 所以请各位算法帝们轻拍啊 嘎嘎 引用 已知线段1(a,b) 和线段2(c,d) ,其中a b c d为端点, 求线段交点p .(平行或共线视作不相交) =============================== 算法一: 求两条线段所在直线的交点, 再

求线段交点&quot;的几种算法(js实现,完整版)

"求线段交点"是一种非常基础的几何计算, 在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法说一说, 希望对大家有所帮助. 本文讲的内容都很初级, 主要是面向和我一样的初学者, 所以请各位算法帝们轻拍啊 嘎嘎 引用 已知线段1(a,b) 和线段2(c,d) ,其中a b c d为端点, 求线段交点p .(平行或共线视作不相交) 算法一: 求两条线段所在直线的交点, 再判断交点是否在两条线段上. 求直线交点时 我们可通过直线的一般方程

求最大子段和的一些算法

public class MaxSubSeqSum { /** * 算法1,穷举搜索 */ public static final int maxSubSeqSum1(int seq[]) { int length = seq.length; int sum = 0; for (int i = 0; i < length; i++) { for (int j = i; j < length; j++) { int theSum = 0; for (int k = i; k <= j; k

求最大公约数 和 最小公倍数 常见算法

#include <stdio.h>int main(){ int a,b,t,c,m,n; scanf("%d%d",&a,&b); m=a; n=b; //1.辗转相除法求最大公约数 /*while(b!=0) { c = a%b; a = b; b = c; } printf("最大公约数: %d\n",a);//最大公约数 printf("最小公倍数: %d\n",m*n/a);//最小公倍数 */ //2.相

machine_learning-knn算法具体解释(近邻算法)

近邻算法是机器学习算法中的入门算法,该算法用于针对已有数据集对未知数据进行分类. 该算法核心思想是通过计算预測数据与已有数据的相似度猜測结果. 举例: 如果有例如以下一组数据(在下面我们统一把该数据作为训练数据): 身高 年龄 国籍 170 23 中国 180 21 美国 185 22 俄国 175 24 中国 120 23 日本 我们将该组数据的前两列作为一个特征值.最后一项作为一个待分类结果.当数据量足够大时,能够通过该数据便可得出较为精确的分类. 比如我们拿到測试数据.年龄23岁,身高17