-
Notifications
You must be signed in to change notification settings - Fork 0
191. Number of 1 Bits #76
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?
Conversation
| コードが見れなくなっていたのでやり取りだけチェック | ||
| この辺りチェックしたら良さそう | ||
| https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation | ||
| C++のもありそうなので探してみる | ||
| https://pkg.go.dev/math/bits#OnesCount | ||
| https://github.com/rihib/leetcode/pull/46 | ||
|
|
||
| 文字列に変換する方法などもある | ||
| https://github.com/Kitaken0107/GrindEasy/pull/24 |
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.
考え方は他の解法にも似ているのですが、全てのbitをチェックする代わりに、最も右にあるbitを消すことで処理するアルゴリズムもあるようです。
Brian Kernighan’s Algorithm
int hammingWeight(unsigned int n) {
int count = 0;
while (n) {
n &= (n - 1);
count++;
}
return count;
}
| int num_bits = 0; | ||
| while (n > 0) { | ||
| if (n % 2 == 1) { | ||
| num_bits +=1; |
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 のあいだにスペースを空けることをおすすめします。
| int num_bits = 0; | ||
| int mask = 1; | ||
| for (int i = 0; i < 32; i++) { | ||
| if ((n & mask) != 0) { |
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.
自分なら mask 変数は使わず、
if ((n & (1 << i)) != 0) {と書くと思います。趣味の範囲だと思います。
| int hammingWeight(int n) { | ||
| int num_bits = 0; | ||
| while (n > 0) { | ||
| if (n % 2 == 1) { |
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.
num_bits += n % 2;とも書けます。趣味の範囲だと思います。
| ## ステップ3 | ||
| **3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。** | ||
|
|
||
| ## 他の解法 |
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.
分割統治法による解法もあります。
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);
return n;「ハッカーのたのしみ: 本物のプログラマはいかにして問題を解くか」に載っています。ソフトウェアエンジニアの常識には含まれていませんが、知っている人はいると思います。
| if (n % 2 == 1) { | ||
| num_bits +=1; | ||
| } | ||
| n /= 2; |
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.
個人的には
n >>= 1;と書きます。コンパイラーで最適化オプションを付けてコンパイルすると、どちらもシフト演算の命令が生成されると思います。ぜひ確かめてみてください。
整数の割り算は遅い、ビット演算は速い、という感覚は持っておいたほうが良いと思います。以下
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/ia32.pdf
からの抜粋です。
Ice Lake and Tiger Lake
| Instruction | Operands | Latency | Reciprocal through put |
|---|---|---|---|
| DIV IDIV | r32 | 12 | 6 |
| SHR SHL SAR | r,i | 1 | 0.5 |
https://zenn.dev/herumi/articles/latency-throughput
CPUにおけるレイテンシ(latency)とは命令が発行されてからその実行が完了するまでの時間(クロックサイクル)です。
Intelのマニュアルによるとスループットとは同じ命令を続けて発行するときに待つclkです。
問題へのリンク
https://leetcode.com/problems/number-of-1-bits/description/
問題文(プレミアムの場合)
備考
次に解く問題の予告
フォルダ構成
LeetCodeの問題ごとにフォルダを作成します。
フォルダ内は、step1.cpp、step2.cpp、step2_2.cpp、step3.cpp、bit_manipulation.cppとmemo.mdとなります。
memo.md内に各ステップで感じたことを追記します。