劍指Offer面試題11(Java版):數值的整數次方

來源:互聯網
上載者:User

標籤:

題目:實現函數double Power(double base,int exponent),求base的exponent次方。不得使用庫函數,同時不需要考慮大數問題

1、自以為很簡單的解法:

由於不需要考慮大數問題,這道題看起來很簡單,可能不少應聘者在看到題目30秒後就能寫出如下的代碼:

public double powerWithExponent(double base,int exponent){double result = 1.0;for(int i = 1;i<= exponent;i++){result = result*base;}return result;}
不錯遺憾的是,寫的快不一定就能得到面試官的青睞,因為面試官會問輸入的指數(exponent)小於1即 是0和負數的時候怎麼辦?上面的代碼完全沒有考慮,只包括了指數為正數的情況。

2、全面但不夠高效的解法,我們離Offer已經不遠了

我們知道當指數為負數的時候,可以先對指數求絕對值,然後算出次方的結果之後再取倒數。既然有求倒數,我們很自然的就要想到有沒有可能對0求倒數,如果對0求倒數怎麼辦?當底數base是零且指數是負數的時候,我們不做特殊的處理,就會發現對0求倒數從而導致程式運行出錯。怎麼告訴函數的調用者出現了這種錯誤?在Java中可以拋出異常來解決。

最後需要指出的是,由於0的0次方在數學上沒有意義的,因此無論是輸出0還是1都是可以接收的,但這都需要和面試官說清楚,表明我們已經考慮到了這個邊界值了。

有了這些相對而言已經全面很多的考慮,我們就可以把最初的代碼修改如下:

/** * 題目:實現函數double Power(double base,int exponent),求base的exponent次方。不得使用庫函數,同時不需要考慮大數問題 * 對於這道題,要考慮四種情況: * 1、底數為0,指數為負數的情況,無意義 * 2、指數為0,返回1 * 3、指數為負數,返回1.0/base,-exponent * 4、指數正數,base,exponent */package swordForOffer;/** * @author JInShuangQi * * 2015年7月30日 */public class E11Power {public double power(double base,int exponent) throws Exception{double result = 0.0;if(equal(base,0.0) && exponent<0){throw new Exception("0的負數次冪無意義");}if(equal(exponent,0)){return 1.0;}if(exponent <0){result= powerWithExponent(1.0/base, -exponent);}else{result = powerWithExponent(base,exponent);}return result;}private double powerWithExponent(double base,int exponent){double result = 1.0;for(int i = 1;i<= exponent;i++){result = result*base;}return result;}//判斷兩個double型資料,電腦有誤差private boolean equal(double num1,double num2){if((num1-num2>-0.0000001) && (num1-num2<0.0000001)){return true;}else{return false;}}public static void main(String[] args) throws Exception{E11Power test = new E11Power();System.out.println(test.power(3, -1));}}
由於電腦表示小數(包括float和double型小數)都會有誤差,我們不能直接用等號(==)判斷兩個小數是否相等。如果兩個小數的差的絕對值很小,比如小於0.0000001,就可以認為他們相等。

此時我們考慮得已經很周詳了,已經能夠得到很多面試官的要求了。但是如果我們碰到的面試官是一個在效率上追求完美的人,那麼他有可能提醒我們函數PowerWithExponent還有更快的辦法。

3、全面而高效的解法,確保我們能拿到Offer

如果輸入的指數exponent為32,我們在函數powerWithExponent的迴圈中需要做31次乘方。但我們可以換一種思路考慮:我們的目標是求出一個數位32次方,如果我們已經知道了它的16次方,那麼只要16次放的基礎上再平方一次就可以了。而16次方又是8次方的平方。這樣以此類推,我們求32次方只需要5次乘方:先求平方,在平方的基礎上求4次方,在4次方的基礎上求8次方,在8次方的基礎上求16次方,最後在16此方的基礎上求32次方。

也就是說我們可以利用下面這個公示求a的n次方:



這個公式就是我們前面利用O(logn)時間求斐波那契數列時,討論的公式,這個公式很容易就能用遞迴實現。新的PowerWithExponent代碼如下:

private double powerWithExponent2(double base,int exponent){if(exponent == 0)return 1;if(exponent == 1)return base;double result = powerWithExponent2(base,exponent >>1);result *= result;if((exponent&0x1) == 1)result *=base;return result;}
最後再提醒一個細節:我們用右移運算代替除2,用位與運算子代替了求餘運算子(%)來判斷一個數是奇數還是偶數。位元運算的效率比乘除法及求餘運算的效率要高很多。既然要最佳化代碼,我們就把最佳化做到極致。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

劍指Offer面試題11(Java版):數值的整數次方

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.