-
Notifications
You must be signed in to change notification settings - Fork 0
50. Pow(x, n) #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
50. Pow(x, n) #45
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| ## 何も見ずに解いてみる | ||
|
|
||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| double myPow(double x, long long n) { | ||
| if (n == 0) { | ||
| return 1; | ||
| } | ||
| if (n < 0) { | ||
| return 1 / myPow(x, -n); | ||
| } | ||
| vector<long long> power_of_2_cache = {1}; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2 の累乗は
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. たしかにシフト演算でできますね! |
||
| while (power_of_2_cache.size() < 32) { | ||
| long long new_power_of_2 = power_of_2_cache.back() * 2; | ||
| if (new_power_of_2 > n) { | ||
| break; | ||
| } | ||
| power_of_2_cache.push_back(new_power_of_2); | ||
| } | ||
| vector<int> n_components_in_power_of_2; | ||
| for (int exp = power_of_2_cache.size() - 1; exp >= 0; --exp) { | ||
| if (power_of_2_cache[exp] <= n) { | ||
| n -= power_of_2_cache[exp]; | ||
| n_components_in_power_of_2.push_back(exp); | ||
| } | ||
| } | ||
| vector<double> power_of_x_cache = {x}; | ||
| for (int exp = 1; exp <= n_components_in_power_of_2.front(); ++exp) { | ||
| power_of_x_cache.push_back(power_of_x_cache.back() * power_of_x_cache.back()); | ||
| } | ||
| double result = 1; | ||
| for (int component : n_components_in_power_of_2) { | ||
| result *= power_of_x_cache[component]; | ||
| } | ||
| return result; | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| n == -2^31 の時に-nがintにcastできなくてエラーになった(intの表現範囲が-2^31 <= n <= 2^31 - 1のため)のでとりあえず関連する型を全部long longにして無理やり通しました | ||
|
|
||
| ## 他の人のコードを見てみる | ||
|
|
||
| https://github.com/tokuhirat/LeetCode/pull/45/files | ||
| https://github.com/ryosuketc/leetcode_arai60/pull/34/files | ||
| https://github.com/Ryotaro25/leetcode_first60/pull/48 | ||
|
|
||
| 自分は非常に面倒なことをしていたらしい。。。 | ||
|
|
||
| ## 最終コード | ||
|
|
||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| double myPow(double x, int n) { | ||
| if (n == 0) { | ||
| return 1.0; | ||
| } | ||
| if (n < 0) { | ||
| // cast to long long to handle INT_MIN; | ||
| return 1.0 / _myPow(x, -(long long)n); | ||
| } | ||
| return _myPow(x, n); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 関数名の先頭にアンダースコアを付けるのは、あまり見ないように思います。チームの平均的な書き方に合わせることをおすすめします。 参考までに、識別子に 2 つの連続するアンダースコアを使用したり、 1 つのアンダースコアのあとに 1 つの大文字が続くものは、 C++ の実装のために予約されています。これらの識別子は使用しないようにしてください。 https://learn.microsoft.com/ja-jp/cpp/cpp/identifiers-cpp?view=msvc-170
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C++ のアンダースコアーから始まる識別子については、次の文字が大文字またはアンダースコアーならば予約済みで、小文字の場合は、グローバルスコープでは予約済みです。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 詳しくありがとうございます。基本的には避けるようにしようと思います。 |
||
| } | ||
| private: | ||
| double _myPow(double x, long long n) { | ||
| double result = 1.0; | ||
| while (n) { | ||
| if (n % 2 == 1) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ただし、 CPU の割り算の命令は一般的に遅いです。そのため、コンパイラーは等価なビット演算に変換できる場合は、それらに置き換える場合があります。この辺りは意識しておいたほうが良いと思います。 以下も参考にすることをお勧めいたします。 |
||
| result *= x; | ||
| } | ||
| x *= x; | ||
| n /= 2; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 自分なら |
||
| } | ||
| return result; | ||
| } | ||
| }; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 良いと思いました。 |
||
| ``` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
自分は浮動小数は 1.0 のように浮動小数であることを明示して書くことが多いです。趣味の範囲かもしれません。
参考までにスタイルガイドへのリンクを貼ります。
https://google.github.io/styleguide/cppguide.html#Floating_Literals
上記のスタイルガイドは唯一絶対のルールではなく、複数あるスタイルガイドの一つに過ぎないということを念頭に置くことをお勧めします。また、所属するチームにより何が良いとされているかは変わります。自分の中で良い書き方の基準を持ちつつ、チームの平均的な書き方で書くことをお勧めいたします。