#
# this is a rather strict implementation of a bit vector class
# it is accessed the same way as an array of python-ints, except
# the value must be 0 or 1
#
#所谓位向量就是由一些二进制位组成的向量。位向量可以用很少的内存来存储Boolean变量。
import sys; rprt = sys.stderr.write #for debugging
#错误处理类,继承自Exception类
class error(Exception):
pass
#检测输入的值是否为整型0或1
def _check_value(value):
if type(value) != type(0) or not 0 <= value < 2:
raise error('bitvec() items must have int value 0 or 1')
#导入数学模块
import math
#计算浮点数当尾数化为大于1的数时的指数.
def _compute_len(param):
'''frexp函数把一个浮点数分解为尾数和指数, mant为尾数,l为指数'''
mant, l = math.frexp(float(param)) #param=mant*2^l
bitmask = 1 << l
if bitmask <= param:#如果2^l小于param
raise ValueError('(param, l) = %r' % ((param, l),))
while l:
bitmask = bitmask >> 1 #相当于让尾数乘2
if param & bitmask:#当尾数变成大于1的数时,退出
break
l = l - 1
return l
#检查并修正key的值
def _check_key(len, key):
if type(key) != type(0):#如果key的类型不是整型,抛出异常
raise TypeError('sequence subscript not int')
if key < 0:
key = key + len
if not 0 <= key < len:#如果key的值的大小不在[0,len)这个区间内,就抛出异常
raise IndexError('list index out of range')
return key
#检查i,j,确保如下关系成立 0<=i<=j<=len
def _check_slice(len, i, j):
#the type is ok, Python already checked that
i, j = max(i, 0), min(len, j)
if i > j:
i = j
return i, j
#位向量类的定义
class BitVec:
def __init__(self, *params):#初始化函数, 接受长度可变参数,最多可接受2个参数
self._data = 0
self._len = 0
if not len(params):#如果没有传递任何参数,什么也不做
pass
elif len(params) == 1:#如果传递一个参数
param, = params
if type(param) == type([]):#参数类型为序列, 由0,1组成
value = 0
bit_mask = 1
for item in param:#设置vlaue的值,根据序列中的每个元素,设置对应的位
# strict check
#_check_value(item)
if item:
value = value | bit_mask
bit_mask = bit_mask << 1
self._data = value
self._len = len(param)
elif type(param) == type(0):#参数为整型
if param < 0:
raise error('bitvec() can/'t handle negative longs')
self._data = param
self._len = _compute_len(param)
else:#参数类型非法
raise error('bitvec() requires array or long parameter')
elif len(params) == 2:#有两个参数,格式为:值,长度
param, length = params
if type(param) == type(0):
if param < 0:
raise error('can/'t handle negative longs')
self._data = param
if type(length) != type(0):#第二个参数必须为整型
raise error('bitvec()/'s 2nd parameter must be int')
computed_length = _compute_len(param)
if computed_length > length:
print('warning: bitvec() value is longer than the length indicates, truncating value')
self._data = self._data & /
((1 << length) - 1)
self._len = length
else:
raise error('bitvec() requires array or long parameter')
else:
raise error('bitvec() requires 0 -- 2 parameter(s)')
#向位向量中添加一个元素
def append(self, item):
#_check_value(item)
#self[self._len:self._len] = [item]
self[self._len:self._len] = /
BitVec(int(not not item), 1)
#计算0或1的数量
def count(self, value):
#_check_value(value)
if value:
data = self._data
else:
data = (~self)._data
count = 0
while data:
data, count = data >> 1, count + (data & 1 != 0)
return count
#找到第一个0或1的位置
def index(self, value):
#_check_value(value):
if value:
data = self._data
else:
data = (~self)._data
index = 0
if not data:
raise ValueError('list.index(x): x not in list')
while not (data & 1):
data, index = data >> 1, index + 1
return index
#向位向量中插入一个元素
def insert(self, index, item):
#_check_value(item)
#self[index:index] = [item]
self[index:index] = BitVec(int(not not item), 1)
#从位向量中移除一个元素
def remove(self, value):
del self[self.index(value)]
#将向量反转
def reverse(self):
#ouch, this one is expensive!
#for i in self._len>>1: self[i], self[l-i] = self[l-i], self[i]
data, result = self._data, 0
for i in range(self._len):
if not data:
result = result << (self._len - i)
break
result, data = (result << 1) | (data & 1), data >> 1
self._data = result
#排序
def sort(self):
c = self.count(1)#计算1的个数
self._data = ((1 << c) - 1) << (self._len - c)#将1置于高位, 其余低位置0
#复制位向量
def copy(self):
return BitVec(self._data, self._len)
#返回位向量序列
def seq(self):
result = []
for i in self:
result.append(i)
return result
#重载__repr__方法
def __repr__(self):
##rprt('<bitvec class instance object>.' + '__repr__()/n')
return 'bitvec(%r, %r)' % (self._data, self._len)
#位向量比较函数
def __cmp__(self, other, *rest):
#rprt('%r.__cmp__%r/n' % (self, (other,) + rest))
if type(other) != type(self):
other = bitvec(other, *rest)
#expensive solution... recursive binary, with slicing
length = self._len
if length == 0 or other._len == 0:
return cmp(length, other._len)
if length != other._len:
min_length = min(length, other._len)
return cmp(self[:min_length], other[:min_length]) or /
cmp(self[min_length:], other[min_length:])
#the lengths are the same now...
if self._data == other._data:
return 0
if length == 1:
return cmp(self[0], other[0])
else:
length = length >> 1
return cmp(self[:length], other[:length]) or /
cmp(self[length:], other[length:])
#返回位向量序列的长度
def __len__(self):
#rprt('%r.__len__()/n' % (self,))
return self._len
#返回key对应的位的值(0或1)
def __getitem__(self, key):
#rprt('%r.__getitem__(%r)/n' % (self, key))
key = _check_key(self._len, key)
return self._data & (1 << key) != 0
#设置key对应的位的值(0或1)
def __setitem__(self, key, value):
#rprt('%r.__setitem__(%r, %r)/n' % (self, key, value))
key = _check_key(self._len, key)
#_check_value(value)
if value:
self._data = self._data | (1 << key)
else:
self._data = self._data & ~(1 << key)
#删除key对应的位
def __delitem__(self, key):
#rprt('%r.__delitem__(%r)/n' % (self, key))
key = _check_key(self._len, key)
#el cheapo solution...
self._data = self[:key]._data | self[key+1:]._data >> key
self._len = self._len - 1
#返回位向量切片[1,j]
def __getslice__(self, i, j):
#rprt('%r.__getslice__(%r, %r)/n' % (self, i, j))
i, j = _check_slice(self._len, i, j)
if i >= j:
return BitVec(0, 0)
if i:
ndata = self._data >> i
else:
ndata = self._data
nlength = j - i
if j != self._len:
#we'll have to invent faster variants here
#e.g. mod_2exp
ndata = ndata & ((1 << nlength) - 1)
return BitVec(ndata, nlength)
#设置位向量切片[i,j]
def __setslice__(self, i, j, sequence, *rest):
#rprt('%s.__setslice__%r/n' % (self, (i, j, sequence) + rest))
i, j = _check_slice(self._len, i, j)
if type(sequence) != type(self):
sequence = bitvec(sequence, *rest)
#sequence is now of our own type
ls_part = self[:i]
ms_part = self[j:]
self._data = ls_part._data | /
((sequence._data | /
(ms_part._data << sequence._len)) << ls_part._len)
self._len = self._len - j + i + sequence._len
#删除位向量切片[i, j]
def __delslice__(self, i, j):
#rprt('%r.__delslice__(%r, %r)/n' % (self, i, j))
i, j = _check_slice(self._len, i, j)
if i == 0 and j == self._len:
self._data, self._len = 0, 0
elif i < j:
self._data = self[:i]._data | (self[j:]._data >> i)
self._len = self._len - j + i
#位向量相加
def __add__(self, other):
#rprt('%r.__add__(%r)/n' % (self, other))
retval = self.copy()
retval[self._len:self._len] = other
return retval
def __mul__(self, multiplier):
#rprt('%r.__mul__(%r)/n' % (self, multiplier))
if type(multiplier) != type(0):
raise TypeError('sequence subscript not int')
if multiplier <= 0:
return BitVec(0, 0)
elif multiplier == 1:
return self.copy()
#handle special cases all 0 or all 1...
if self._data == 0:
return BitVec(0, self._len * multiplier)
elif (~self)._data == 0:
return ~BitVec(0, self._len * multiplier)
#otherwise el cheapo again...
retval = BitVec(0, 0)
while multiplier:
retval, multiplier = retval + self, multiplier - 1
return retval
#定义位向量的与操作
def __and__(self, otherseq, *rest):
#rprt('%r.__and__%r/n' % (self, (otherseq,) + rest))
if type(otherseq) != type(self):
otherseq = bitvec(otherseq, *rest)
#sequence is now of our own type
return BitVec(self._data & otherseq._data, /
min(self._len, otherseq._len))
#定义位向量的异或操作
def __xor__(self, otherseq, *rest):
#rprt('%r.__xor__%r/n' % (self, (otherseq,) + rest))
if type(otherseq) != type(self):
otherseq = bitvec(otherseq, *rest)
#sequence is now of our own type
return BitVec(self._data ^ otherseq._data, /
max(self._len, otherseq._len))
#定义位向量的或操作
def __or__(self, otherseq, *rest):
#rprt('%r.__or__%r/n' % (self, (otherseq,) + rest))
if type(otherseq) != type(self):
otherseq = bitvec(otherseq, *rest)
#sequence is now of our own type
return BitVec(self._data | otherseq._data, /
max(self._len, otherseq._len))
#定义位向量的逆操作
def __invert__(self):
#rprt('%r.__invert__()/n' % (self,))
return BitVec(~self._data & ((1 << self._len) - 1), /
self._len)
#定义位向量的整型转换操作
def __int__(self):
return int(self._data)
#定义位向量的浮点型转换操作
def __float__(self):
return float(self._data)
bitvec = BitVec