统计一个数值中二进制中1的个数。
def countOnes(x): count = 0 while x > 0: count += 1 x &= (x - 1) # x=0b111 x-1=0b110 &= 0b110 1个 # x=0b110 x-1=0b101 &= 0b100 2个 # x=0b100 x-1=0b011 &= 0b000 3个 return count # 计算其中0的个数 import math def countZeros(x): count = 0 while x > 0: count += 1 x &= (x - 1) return int(math.log(x) + 1) -count
在数组中找a,b 使得a+b=c
def binarysearch(L,m): # 折半查找 if len(L) == 0: return -1 i = int(len(L) / 2) if a[i] == m: return i if a[i] > m: return binarysearch(L[0:i],m) if a[i] < m and i+1 < len(L): return binarysearch(L[i+1:],m) return -1 L.sort() # 排序
求两数的公约数。
def gcd(a, b): if a % b == 0: return b d = a % b return gcd(b, d) # a b的公约数等于 b d 的公约数
指定进制的字符和数字转换
def strToInt(str, b): # 字符转数值 val = 0 base = 1 i = len(str) - 1 while i >= 0: # 从最后一位开始 c = str[i] v = 0 if '0' <= c <= '9': # 判断此位是几 v = ord(c) - ord('0') if 'A' <= c <= 'E': v = 10 + ord(c) - ord('A') if i < len(str) - 1: # 位权最大是 len(str)-1 第一次不执行 base=1 base *= b val += v * base i -= 1 return val def intToStr(v, b): # 数值转字符 s = '' c = '0' while v > 0: d = v % b # 辗转取余 if 0 <= d <= 9: c = chr(ord('0') + d) if d >= 10: c = chr(ord('A') + d - 10) s = c + s # 倒排 v //= b # 整除 return s
eliasgamma编码 把一个数转换为二进制 ,并在高位增加长度-1个0
def eliaasGammaEncode(n): # 编码 s = intToBinaryString(n) # 数值转二进制字符串 s = addZerosToHead(s) # 在高位补0 return s def intToBinaryString(n): s = '' while n > 0: if n & 1 == 0: # 每次取最后一位,增加到s里 s = '0' + s else: s = '1' + s n = n >> 1 # 向右移动,以取得每一位数 return s def addZerosToHead(s): i = len(s) while i - 1 > 0: # 增加长度-1个0 s = '0' + s i -= 1 return s def eliasGammaDecode(s): length = getHeadZerosCount(s) # 得到补0的位数 if length <= 0: raise Exception("Head Zeros error") s = s[length:] # 取得补0后面的值 binary = s[:length + 1] # 取得这个数 n = binaryStringToInt(binary) # 二进制字符转数值 return n def getHeadZerosCount(s): cut = 0 for i in range(len(s)): if s[i] == '0': # 统计0的个数 cut += 1 else: break return cut def binaryStringToInt(s): n = 0 for i in range(len(s)): if s[i] == '1': # 还原这个数 n |= 1 if i < len(s) - 1: n = n << 1 return n
位运算实现乘法和加法
def binaryAdd(x, y): # 加法实现 v = 0 # 结果 advance = 0 # 进位标志 r = 0 # 结果中的位置 while x > 0 or y > 0: i = x & 1 # 取最后一位 j = y & 1 x = x >> 1 y = y >> 1 b = i ^ j # 异或 1^0 0^1 为真 if b == 1: if advance == 1: # 如果这时有进位 1+0+advace=10 进位标志保持 b = 0 # b = 0 else: if i & j == 1: # i ,j 都是1 if advance == 1: # advance 为1 i+j+advance = 11 b=1 进位标志保持 b = 1 else: # advance 为0 i+j+advance =10 进位标志置1 b=0 b = 0 advance = 1 else: # i,j都为0 if advance == 1: # i+j+advance=1 b=1 进位标志置0 b = 1 # i+j+advance=0 b=0 进位标志不变 advance = 0 b = b << r v |= b r += 1 if advance == 1: v |= (advance << r) return v def binaryMultiply(a, b): # 乘法实现 stack = [] # 利用列表实现栈 s = 0 while b > 0: # a*b 每次把a左移后压栈,直到b为0 if b & 1 == 1: # b为1 就左移后压栈 stack.append(a << s) else: stack.append(0) # b为0 不压栈 b = b >> 1 # 右移一位,取下一个1 s += 1 # b向左移动n位 while len(stack) > 1: # 直到最后只有一个元素,就是结果 x = stack.pop() y = stack.pop() z = binaryAdd(x, y) # 把x,y求各后再次压栈 stack.append(z) return stack.pop()
把一个列表进行划分,分为 小于,等于,大于目标值的列表,原地进行划分
def rearrangeArray(array, i): if len(array) <= 1: return array pivot = array[i] array = rearrangeByPivot(array, 0, len(array) - 1, pivot, True) j = 0 # 分成两部分,前边大于piovt 后边的小于pivot for j in range(len(array)): if array[j] >= pivot: # 找到第一个大于pivot的值 break array = rearrangeByPivot(array, j, len(array) - 1, pivot, False) return array # 对后一部分进行调整 def rearrangeByPivot(array, begin, end, pivot, checkEqual): if end <= begin: return while begin < end: if (checkEqual is True and array[begin] >= pivot) or (checkEqual is False and array[begin] > pivot): array[begin], array[end] = array[end], array[begin] end -= 1 # begin大于pivot 交换 ,end向前 这样换过来的都是大于pivot的 else: begin += 1 # begin不大于或小于,begin 向后,前边的是小于等于pivot的值 return array
从列表中找到连续的一组元素的和,取余列表长度等于0
def findModuleSubSet(A): boxes = [] # 定义一个盒子,用于标志是否出现过这个余数 for i in range(len(A)): boxes.append(0) sum = 0 subSet = [] # 存放满足要求的数组下标 for k in range(len(A)): sum += A[k] subSet.append(k) t = sum % len(A) if t == 0: return subSet # 如果等于0 满足条件,返回下标 if boxes[t] != 0: # 这个盒子有值,说明这个余数出现过 preSum = 0 for i in range(k + 1): preSum += A[i] if preSum % len(A) == t: # 若这两个值一样,说明后来的preSum与T之间的数取余 return subSet[i + 1:] # 为0 所以返回i+1 后最后的下标 boxes[t] = 1 return []