-
Notifications
You must be signed in to change notification settings - Fork 0
Reverse Bits #148
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?
Reverse Bits #148
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,52 @@ | ||
| # 190. Reverse Bits | ||
|
|
||
| ## step1 | ||
| strに直してreverseする。f-stringのフォーマットが分からず、調べた。 | ||
|
|
||
| https://docs.python.org/ja/3/tutorial/inputoutput.html#formatted-string-literals | ||
| https://docs.python.org/ja/3/library/string.html#formatspec | ||
|
|
||
| bが2進数、x (Xで大文字)で16進数、#を付けるとプレフィックスが付く | ||
|
|
||
| 0(桁数)で0埋め。他を書くときには><^などを書く | ||
|
|
||
| ```python | ||
| >>> num = 42 | ||
| >>> print(f"{num:b}") | ||
| 101010 | ||
| >>> print(f"{num:x}") | ||
| 2a | ||
| >>> print(f"{num:#x}") | ||
| 0x2a | ||
| >>> print(f"{num:#X}") | ||
| 0X2A | ||
| >>> print(f"{num:03b}") | ||
| 101010 | ||
| >>> print(f"{num:03x}") | ||
| 02a | ||
| >>> print(f"{num:-3x}") | ||
| 2a | ||
| >>> print(f"{num:,3x}") | ||
| Traceback (most recent call last): | ||
| File "<stdin>", line 1, in <module> | ||
| ValueError: Invalid format specifier ',3x' for object of type 'int' | ||
| >>> print(f"{num:,>3x}") | ||
| ,2a | ||
| >>> print(f"{num:,^6x}") | ||
| ,,2a,, | ||
| ``` | ||
|
|
||
| bit演算でも書く。 | ||
|
|
||
| ## step2 | ||
| https://github.com/Kitaken0107/GrindEasy/pull/23 | ||
|
|
||
| > 文字列に変換しないでやってみてください。ビット操作の問題だと思います。 | ||
|
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. 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 が速くなってあまり見なくなりましたね。
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. 昔と比べて1000倍ほど速くなっているようですね。今のCPUのクロック数が3~6Ghzあたりというのは覚えておこうと思います。 |
||
|
|
||
| > 32 bit 整数って、シフト演算をして、最下位ビットを見ると、スタックみたいなものじゃないですか。 | ||
|
|
||
| --- | ||
| 以下を追加 | ||
| - builtin (c++) | ||
| - divide and conquer | ||
| - 配列を前計算しておく | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class Solution: | ||
| def reverseBits(self, n: int) -> int: | ||
| bit_expression = f"{n:032b}" | ||
| return int(bit_expression[::-1], 2) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| class Solution: | ||
| def reverseBits(self, n: int) -> int: | ||
| reversed_bits = 0 | ||
| num_bits = 0 | ||
| while num_bits < 32: | ||
| reversed_bits <<= 1 | ||
| reversed_bits |= n & 1 | ||
| n >>= 1 | ||
| num_bits += 1 | ||
| return reversed_bits | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| #include <cstdint> | ||
|
|
||
| class Solution { | ||
| public: | ||
| uint32_t reverseBits(uint32_t n) { | ||
| return __builtin_bitreverse32(n); | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| class Solution: | ||
| def reverseBits(self, n: int) -> int: | ||
| n = n & 0xffffffff | ||
| n = ((n & 0x55555555) << 1) | ((n & 0xaaaaaaaa) >> 1) | ||
| n = ((n & 0x33333333) << 2) | ((n & 0xcccccccc) >> 2) | ||
| n = ((n & 0x0f0f0f0f) << 4) | ((n & 0xf0f0f0f0) >> 4) | ||
| n = ((n & 0x00ff00ff) << 8) | ((n & 0xff00ff00) >> 8) | ||
| n = ((n & 0x0000ffff) << 16) | ((n & 0xffff0000) >> 16) | ||
|
|
||
| return n & 0xffffffff |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Solution: | ||
| REVERSE_TABLE = [0] * 256 | ||
|
|
||
| @classmethod | ||
| def init_table(cls): | ||
| for i in range(1, 256): | ||
| cls.REVERSE_TABLE[i] = (cls.REVERSE_TABLE[i >> 1] >> 1) | ((i & 1) << 7) | ||
|
|
||
| def __init__(self): | ||
| if self.REVERSE_TABLE[1] == 0: | ||
| self.init_table() | ||
|
|
||
| def reverseBits(self, n: int) -> int: | ||
| n = n & 0xffffffff | ||
|
|
||
| byte0 = self.REVERSE_TABLE[n & 0xff] | ||
| byte1 = self.REVERSE_TABLE[(n >> 8) & 0xff] | ||
| byte2 = self.REVERSE_TABLE[(n >> 16) & 0xff] | ||
| byte3 = self.REVERSE_TABLE[(n >> 24) & 0xff] | ||
|
|
||
| return (byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3 |
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.
分割統治法で解く方法もあります。興味があれば探してみて下さい。ソフトウェアエンジニアの常識には含まれていないと思いますが、「ハッカーのたのしみ」に書かれており、これを読んだソフトウェアエンジニアなら知っていると思います。
https://www.amazon.co.jp/%E3%83%8F%E3%83%83%E3%82%AB%E3%83%BC%E3%81%AE%E3%81%9F%E3%81%AE%E3%81%97%E3%81%BF%E2%80%95%E6%9C%AC%E7%89%A9%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AF%E3%81%84%E3%81%8B%E3%81%AB%E3%81%97%E3%81%A6%E5%95%8F%E9%A1%8C%E3%82%92%E8%A7%A3%E3%81%8F%E3%81%8B-%E3%82%B8%E3%83%A5%E3%83%8B%E3%82%A2-%E3%83%98%E3%83%B3%E3%83%AA%E3%83%BC%E3%83%BBS-%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AC%E3%83%B3/dp/4434046683
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.
(pushするのを忘れていました。)
この解法は自分では全く思いつきませんでした。「ハッカーのたのしみ」はビット演算について詳しく書かれた本のようですね。機会があれば手に取ってみようと思います。