zoukankan      html  css  js  c++  java
  • 剑指Offer--第16题 数值的整数次方

    第16题 数值的整数次方

    题目:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
    思路 看到有点懵,第一感觉觉得是不是应该考虑0的0次或者负数情况,还有就是浮点类型没办法使用"="号,最后自己以偷懒的方式直接调用Java的API,如果面试题中不让调用库函数,那么基本上这题就是挂了可能。
    以上题目描述来自牛客,没有对使用做限制。真正的剑指offer上有限制条件不得使用库函数,同时不需要考虑大数问题。

    自己的low代码

    public class Solution {
        public double Power(double base, int exponent) {
             return Math.pow(base, exponent);
      }
    }
    

    剑指offer思路::需要将所有情况考虑全面:base可为正、0和负,同样exponent也可以为正、0和负。1、当base为0,exponent为负时,这是一种常见的异常,分为为0异常;2、当exponent为0时;3、expoonent为负;4、考虑运行效率问题;
    结果正确,但效率不高的写法:

    public class Solution {
        public double Power(double base, int exponent) {
    		if(base==0&&exponent<0) {
    			return 0;
    		}
    		if(exponent==0) { //这样判断是合理的;
    			return 1;
    		}
    		
            int ex = exponent;
    		if(exponent<0){  //容易忽略;
    			ex = -exponent;
    		}
    		double result = 1;
    		for(int i=0;i<ex;i++ ) { //效率不高;
    			result *= base;
    		}
    		if(exponent<0) {
    			result=1/result;
    		}
    		return result;
        
    	  }
    }
    

    问题:除了使用for循环外,还有就是double为0等号的使用,之前一直有一个错觉就是浮点类型不能使用等号判断,因为不准确,所以对这种写法第一反应就是不正确。但是看了看了网上的解释发现,其实这种写法有道理的,因为

    回复于 2013-11-27 09:55:46 #5 得分:5
    首先一个 double 是否为 0,或者其他的数值,是精确的,可以使用== 。
    比如 double f = 0; 此时 f 是精确为 0 ,f == 0 为 true。
    但是,double 在运算中,由于截尾的原因,总是有误差的。而此时是否为0,要看你的这个运算的精度要求。
    比如运算后,f = 0.001,此时不能简单去和 e 去比较。
    

    简单来说,就是如果你所要比较的那个值如果是精确的那么比较就是精确的,如果本身存在截取,那么使用就不正确。
    对for循环进行改进

    public class Solution {
        public double Power(double base, int exponent) {
    		if(base==0&&exponent<0) {
    				return 0;
    			}
    			int ex = exponent;
    			if(exponent<1){
    				ex = -exponent;
    			}
    			double result = Power3(base,ex);
    			if(exponent<0) {
    				result=1/result;
    			}
    			
    			
    			return result;
    		  }
    		public double Power3(double base, int exponent) {
    			if(exponent ==0 ) {
    				return 1;
    				
    			}
    			if(exponent==1) {
    				return base;
    			}
    			double result = Power3(base,exponent>>1);
    			result *=result;
    			if((exponent&1)==1) {//奇偶判断
    				result *=base;
    				
    			}
    			
    			return result;
    		}
    }
    

    优雅写法

    链接:https://www.nowcoder.com/questionTerminal/1a834e5e3e1a4b7ba251417554e07c00
    来源:牛客网
    
    /**
     * 1.全面考察指数的正负、底数是否为零等情况。
     * 2.写出指数的二进制表达,例如13表达为二进制1101。
     * 3.举例:10^1101 = 10^0001*10^0100*10^1000。
     * 4.通过&1和>>1来逐位读取1101,为1时将该位代表的乘数累乘到最终结果。
     */
    public double Power(double base, int n) {
        double res = 1,curr = base;
        int exponent;
        if(n>0){
            exponent = n;
        }else if(n<0){
            if(base==0)
                throw new RuntimeException("分母不能为0"); 
            exponent = -n;
        }else{// n==0
            return 1;// 0的0次方
        }
        while(exponent!=0){
            if((exponent&1)==1)
                res*=curr;
            curr*=curr;// 翻倍
            exponent>>=1;// 右移一位
        }
        return n>=0?res:(1/res);       
    }
    
    
    多思考,多尝试。
  • 相关阅读:
    本地连不上远程mysql数据库(2)
    linux后台执行命令:&和nohup
    uva 10806 Dijkstra, Dijkstra. (最小费最大流)
    VS2013带来的&quot;新特性&quot;
    HDOJ 5091 Beam Cannon 扫描线
    2014百度之星资格赛4题
    二维码登陆
    安装Sublime配合quick-cocos2d-x开发
    J2SE核心开发实战(二)——字符串与包装类
    LeetCode_3Sum Closest
  • 原文地址:https://www.cnblogs.com/LynnMin/p/9282700.html
Copyright © 2011-2022 走看看