ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

算法练习

2021-04-10 18:33:17  阅读:211  来源: 互联网

标签:advance return 练习 len 算法 pivot array def


0x001

统计一个数值中二进制中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

0x002

在数组中找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() # 排序

0x003

求两数的公约数。

def gcd(a, b):
    if a % b == 0:
        return b
    d = a % b
    return gcd(b, d)
# a b的公约数等于 b d 的公约数

0x004

指定进制的字符和数字转换

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

0x005

eliasgamma编码 把一个数转换为二进制 ,并在高位增加长度-1个0

  • x=12 0b1100 编码后 0b0001100
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

0x006

位运算实现乘法和加法

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()

0x007

把一个列表进行划分,分为 小于,等于,大于目标值的列表,原地进行划分

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

0x008

从列表中找到连续的一组元素的和,取余列表长度等于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 []

标签:advance,return,练习,len,算法,pivot,array,def
来源: https://blog.csdn.net/QTT_Rookie/article/details/115581692

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有