我當時正在玩創建一個小棋子解算器的想法。首先,我會製作一個非常小巧的跳棋板,然後繼續構建遊戲樹等。將64位整數中的每一位比較爲一個32位整數
標準跳棋板具有8行,和4官能列(跳棋只能移動對角線)。這給了我們32個職位!每個位置需要的3位信息... king
位,並color
位...所以00
是非王黑,01
是非王衝,10
是王黑,11
是王衝。這給了我們64這是一個很好的數字來處理(長整數的確切大小)。
但是,每個檢查器還需要一個附加位... isOccupied
位,因爲每個檢查器位置可以是空的,或者填充上述四個狀態之一。我決定採用64個狀態,並將它們放入一個長64位的int中,並將這32個狀態放入一個32位整數中。
所以,現在我們有一些背景,我有以下問題:我想輕鬆地說:「這個板上有多少紅色棋子?」那麼這不是那麼糟糕...我們的64位整數保存這樣的數據:
king_color_king_color_king_color
所以011001
意味着我們有紅色,黑色的國王,紅色。
爲了得到顏色信息,我們可以使用位掩碼01010101 ... 01,它是十六進制的0x5555555555555555。這將國王位清零,只留下顏色位。因此,在與掩碼「與」之後的011001示例中,我們有010001.如果我們計算位數(popcount
,bitcount
),我們可以得到紅色的數量......
啊,但是等等!這些顏色可能不是「正在使用」。我們必須檢查我們的32位int以查看給定的檢查器是否正在使用中!所以說我們對於我們佔用的32個整數有011個......這意味着第一個檢查者,上面的01(紅色非王)...實際上沒有被佔用......它只是一個空的方塊。如果我們要在那裏移動另一個檢查器,我們可能需要也可能不需要更新這兩個特殊顏色位。所以,把他們放在一起
32bit = 011
64bit = 011001
代表3個檢查位置...一個空的檢查與以前是紅色,其次是黑王,其次是紅色。一旦我們做了64位掩碼010101操作我們得到:
64bitWithMask = 010001
32bit=011
天真我們有2個紅色...但我們實際上只有1個活動......我想做些什麼基本上採取奇數位64位的字符串,並將它們與32位字符串中的每一位進行邏輯與運算......即
1 AND 0, 0 AND 1, 1 AND 1
給我們001代表紅色檢測器的計數。
或等價地,將64bitWithMask
轉換爲64bitWithMaskOddBits = 101
然後簡單地用AND與32位得到011 & 101 = 001
。
那麼形式上,有沒有辦法取一個長度爲2X的比特串,並通過只取其奇數比特來將它縮小到長度X?我努力避免循環,ifs等,只使用邏輯(和,或,異或,否定等)。
當然或者,如果有另一種戰略,以獲得給我的32位和64位串紅的正確計數。 謝謝!
編輯:
的解決我提出的是優雅的接受的答案下面解決了這個問題,但我的實際應用中更好的解決方案是對64位代表分成兩個32這節省了我一堆的操作來提取我需要的東西。感謝LukeG和Tehtmi的幫助!我很高興能夠接觸到這種位操作的新技術,「平行」。
在奇數位上移位運算符,並使用適當的掩碼進行AND – Ripi2
或者您可以將這些圖層分開存儲在首位。你爲什麼不使用一個32位整數作爲王位,一個是彩色位,另一個是佔位位? – 2017-07-29 00:01:16
爲什麼不將數據存儲在兩個64位整數中?好吧,這會留下32位未使用,但您也可以組織如何使用/設置位,以便進行簡單的按位比較。或者簡單地使用3個32位整數,而不是在64位變量中交錯。 – Peter