剣指offer面接問題11_数値の整数次数(*)
2806 ワード
テーマ:関数double Power(double base,int exponent)を実現して、baseのexponentの次の方を求めます.ライブラリ関数は使用できませんが、大きな数の問題を考慮する必要はありません.
この問題を通じて、注意していない知識点を理解します.
1、変数の命名は合理的かつ明瞭である
2、コードの完全性を確保し、三つの角度から着手する.
1)機能テスト:本体機能の確保
2)境界テスト:各種境界値を考慮する
3)負のテスト:各種の可能なエラー入力を考慮する
3、コードの効率性、性能テスト:コードの実行効率を考慮する
4、3種類のエラー処理方法:
1)呼び出し元にエラーがないかを関数で返す
2)エラーが発生した場合、グローバル変数を設定する
3)異常、関数の実行中にエラーが発生した場合、1つの異常を放出する.
上記の問題について、その答えは以下の通りです.
解決方法1:
基本機能,すなわち指数が正の場合のみ実現し,他の入力は考慮されない.
解決方法2:
コードの整合性を考慮
解決方法3:
コード性能を考慮すると、2^16=(2^8)^2=((2^4)^2)^2.......などの順番に類推して、このように多くの繰り返し計算を減らしたので、上のコードの一部を変更します.
1、再帰を使う(上の過程を考え、再帰を理解するのに役立つ)
2、ビットで演算し、左に1ビット移動し、2で割ることを表し、余剰(%2)の代わりに和演算で奇数か否かを判断する.ビット演算効率が向上します.
上の問題を通して、学びました.
1、簡単な問題は全面的に考えなければならない.
2、どのように2つの小数が等しいかどうかを判定して、"=="を使うことができなくて、両者の間の差の絶対値を比較して、1つのとても小さい範囲内にあります.
3、ビット演算が上手で、効率を高めることができます.
4、再帰を複雑に考えない
【上記のコードと比較して、各ステップの再帰プロセス(どのように再帰するか、どのように前のステップに戻るかを含む)を考慮すると複雑になります.
しかし全体的に見ると、一歩ずつやるべきことであり、本題にとってはresult*=resultである.その他のいくつかのif判断条件は全体の過程で考慮する必要がある.
/*点滴蓄積、私の一歩O(∩∩)O~*/
この問題を通じて、注意していない知識点を理解します.
1、変数の命名は合理的かつ明瞭である
2、コードの完全性を確保し、三つの角度から着手する.
1)機能テスト:本体機能の確保
2)境界テスト:各種境界値を考慮する
3)負のテスト:各種の可能なエラー入力を考慮する
3、コードの効率性、性能テスト:コードの実行効率を考慮する
4、3種類のエラー処理方法:
1)呼び出し元にエラーがないかを関数で返す
2)エラーが発生した場合、グローバル変数を設定する
3)異常、関数の実行中にエラーが発生した場合、1つの異常を放出する.
上記の問題について、その答えは以下の通りです.
解決方法1:
基本機能,すなわち指数が正の場合のみ実現し,他の入力は考慮されない.
double Power0(double base, int exponent)
{
double result = 1.0;
for(int i = 1; i < exponent; i++)
{
result *= base;
}
return result;
}
解決方法2:
コードの整合性を考慮
/** double , == , */
bool Equal_double(double num1,double num2)
{
if((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
return true;
else
return false;
}
/** */
double Power_with_unsigned_int(double base,unsigned int exponent)
{
double result = 1.0;
for(unsigned int i = 1; i <= exponent; i++)
{
result *= base;
}
return result;
}
bool g_InvalidInput = false; /** , */
double Power1(double base, int exponent)
{
/* 0.0 */
if(Equal_double(base,0.0) && exponent <= 0)
{
g_InvalidInput = true;
return 0.0;
}
else if(Equal_double(base,0.0) && exponent > 0)
return 0.0;
unsigned int absExponent = (unsigned int)(exponent);
if(exponent < 0)
absExponent = (unsigned int)(-exponent);
//cout << "absExponent = " << absExponent << endl;
double result = Power_with_unsigned_int(base,absExponent);
/* , */
if(exponent < 0)
result = 1.0 / result;
return result;
}
解決方法3:
コード性能を考慮すると、2^16=(2^8)^2=((2^4)^2)^2.......などの順番に類推して、このように多くの繰り返し計算を減らしたので、上のコードの一部を変更します.
double Power_with_unsigned_int_efficiently(double base, unsigned int exponent)
{
if(exponent == 0)
return 1;
if(exponent == 1)
return base;
double result = Power_with_unsigned_int_efficiently(base, exponent >> 1);
result *= result;
if(exponent & 0x1 == 1) // base,%2==0, 0
result *= base;
return result;
}
の上のコードは、1、再帰を使う(上の過程を考え、再帰を理解するのに役立つ)
2、ビットで演算し、左に1ビット移動し、2で割ることを表し、余剰(%2)の代わりに和演算で奇数か否かを判断する.ビット演算効率が向上します.
上の問題を通して、学びました.
1、簡単な問題は全面的に考えなければならない.
2、どのように2つの小数が等しいかどうかを判定して、"=="を使うことができなくて、両者の間の差の絶対値を比較して、1つのとても小さい範囲内にあります.
3、ビット演算が上手で、効率を高めることができます.
4、再帰を複雑に考えない
【上記のコードと比較して、各ステップの再帰プロセス(どのように再帰するか、どのように前のステップに戻るかを含む)を考慮すると複雑になります.
しかし全体的に見ると、一歩ずつやるべきことであり、本題にとってはresult*=resultである.その他のいくつかのif判断条件は全体の過程で考慮する必要がある.
/*点滴蓄積、私の一歩O(∩∩)O~*/