zoukankan      html  css  js  c++  java
  • 面试题:不使用数学库求平方根

    面试题:不使用数学库求平方根

    此题考查的是面试者的二分法和迭代相关的数学逻辑能力。

    思路说明

    每次查找区间内的中间值,判断他是否能够达到标准。假如要查找2的平方根,我们取1和2的中间数1.5,而1.5^2=2.25 大于2,则我们需要从1和1.5区间内在找一个中间值1.25。而1.25^2=1.5625,小于2,所有我们取1.25到1.5的中间数,然后一直继续下去,直到满足我们的要求。

    代码示例

    package top.enjoyitlife.interview;
    
    /**
     * @ClassName: CalculateApproximateValue
     * @Description: 求近似值。不使用数学公式求得平方根的近似值
     * @Author: MegaSlark
     * @Date: 2019/12/23
     */
    public class CalculateApproximateValue {
    
    
        public static void main(String[] args) {
            //使用数学计算公式 这里就是提一下 通过自带的函数库得到的值
            double result = Math.sqrt(2);
            System.out.println(result);
    
            //二分法迭代
            CalculateApproximateValue cav = new CalculateApproximateValue();
            cav.nums = 2;
            cav.precision = 0.00000000001d;
            double myResult = cav.calculate(cav.nums);
            System.out.println(myResult);
    
    	// for循环方式
            double myResult2 = cav.calculateSquareRoot2(2, cav.precision);
            System.out.println(myResult2);
        }
    
    
        //    方法计算次数
        private int calculateTimes;
        //    精度误差
        private double precision;
        //    需要求近似值的元数据
        private double nums;
    
        /***
         * 迭代法求近似值的方法
         * @param num
         * @return double 平方根
         */
        private double calculate(double num) {
            return calculateSquareRoot(1, num);
        }
    
         /***
         * 迭代法求近似值的方法
         * @param num
         * @return double 平方根
         */
        public double calculateSquareRoot(double min, double max) {
            calculateTimes++;
            double mid = (min + max) / 2;
            double tempNums = mid * mid;
            if (Math.abs(tempNums - nums) > precision) {
                if (mid * mid < nums) {
                    min = mid;
                } else {
                    max = mid;
                }
                return calculateSquareRoot(min, max);
            } else {
                return mid;
            }
        }
    
        /***
        *for循环计算平方根近似值
        */
        private double calculateSquareRoot2(double num,  double precision) {
            double min = 1d;
            double max = num;
            for (;;) {
                double middle = (min + max) / 2;
                double square = middle * middle;
                double delta = Math.abs((square / num) - 1);
                if (delta <= precision) {
                    return middle;
                } else {
                    if (square > num) {
                        max = middle;
                    } else {
                        min = middle;
                    }
                }
            }
        }
    }
    

    说明

    上面的代码提供了两种实现的方式,一种是通过迭代的方式,一种是通过for循环的方式,当然我们也可以将for换成while循环的方式,这两个方式略有差异,但是本质就是上面说的思路,不断的计算中间值,直到满足我们需要的精度标准。

    补充

    这里在补充一点,Java里面的double类型数据,是双精度64bit浮点数,通常10进制的有效位数只有14位下,超过14位就会失真,所以14位是许多软件推荐的最大显示位,如果将题目的精度要求到15位,那么我们就需要将double类型改为bigdecimal,可以保留15位10进制有效数字。

  • 相关阅读:
    POJ1486 Sorting Slides 二分图or贪心
    POJ2060 Taxi Cab Scheme 最小路径覆盖
    POJ3083 Children of the Candy Corn 解题报告
    以前的文章
    POJ2449 Remmarguts' Date K短路经典题
    这一年的acm路
    POJ3014 Asteroids 最小点覆盖
    POJ2594 Treasure Exploration 最小路径覆盖
    POJ3009 Curling 2.0 解题报告
    POJ2226 Muddy Fields 最小点集覆盖
  • 原文地址:https://www.cnblogs.com/enjoyitlife/p/12088868.html
Copyright © 2011-2022 走看看