最右边n个整数的人口数

时间:2010-12-27 00:46:37

标签: data-structures haskell hash bit-manipulation

我正在Haskell中实现Bagwell's Ideal Hash Trie。为了找到子特里的元素,他说要做以下事情:

  

找到符号s的弧,   需要找到相应的位   在位图然后计数   它在地图下面的一位   计算有序的索引   子字典树。

最好的方法是什么?听起来最简单的方法是select the bits below that bit并对结果数进行人口统计。有更快或更好的方法吗?

1 个答案:

答案 0 :(得分:4)

是。特别是,可以使mask和popcount非常有效。以下是Clojure实现的内容:

static int mask(int hash, int shift){
    //return ((hash << shift) >>> 27);// & 0x01f;
    return (hash >>> shift) & 0x01f;
}

...

static int bitpos(int hash, int shift){
    return 1 << mask(hash, shift);
}

final int index(int bit){
    return Integer.bitCount(bitmap & (bit - 1));
}

...

public INode assoc(int levelShift, int hash, Object key, Object val, Box addedLeaf){
    int bit = bitpos(hash, shift);
    int idx = index(bit);
    if((bitmap & bit) != 0)

以下是我在my implementation in Haskell中所做的事情:

type Key    = Word
type Bitmap = Word
type Shift  = Int
type Subkey = Int -- we need to use this to do shifts, so an Int it is

-- These architecture dependent constants

bitsPerSubkey :: Int
bitsPerSubkey = floor . logBase 2 . fromIntegral . bitSize $ (undefined :: Word)

subkeyMask :: Bitmap
subkeyMask = 1 `shiftL` bitsPerSubkey - 1

maskIndex :: Bitmap -> Bitmap -> Int
maskIndex b m = popCount (b .&. (m - 1))

mask :: Key -> Shift -> Bitmap
mask k s = shiftL 1 (subkey k s)

{-# INLINE subkey #-}
subkey :: Key -> Shift -> Int
subkey k s = fromIntegral $ shiftR k s .&. subkeyMask