标签 算法 下的文章

Python 二进制转十进制

二进制转十进制的原理相对简单。
假设有二进制数为abc.def,对应的十进制数为A.B
那么整数部分A = a*2^2 + b*2^1 + c*2^0, 小数部分B = d*2^(-1) + e*2^(-2) + f*2^(-3)
实现程序如下:

# 二进制转十进制
def binary_to_decimal(binary):
    decimal = 0
    integer_part, fractional_part = binary.split('.')  # 拆分整数部分和小数部分

    # 转换整数部分为十进制
    for i in range(len(integer_part)):
        digit = int(integer_part[i])
        power = len(integer_part) - i - 1
        decimal += digit * (2 ** power)

    # 转换小数部分为十进制
    for i in range(len(fractional_part)):
        digit = int(fractional_part[i])
        power = -(i + 1)
        decimal += digit * (2 ** power)

    return decimal

Python 十进制(可包含小数)转二进制

原理

假设有十进制数A.B,对应的二进制数为abc.def
整数部分A = a*2^2 + b*2^1 + c*2^0,所以当A除以2时,得到a*2^1 + b*2^0和余数c除2取余)。
同理,小数部分B = d*2^(-1) + e*2^(-2) + f*2^(-3),当B乘以2时,B*2 - d = e*2^(-1) + f*2^(-2),即 B*2的整数部分求出了d乘2取整)。

所以十进制转换成二进制算法如下:

def decimal_to_binary(decimal):
    integer_part = int(decimal)  # 提取整数部分
    fractional_part = decimal - integer_part  # 提取小数部分

    # 转换整数部分为二进制
    binary_integer = ""
    if integer_part == 0:
        binary_integer = "0"  # 十进制数为0时,二进制为0
    else:
        while integer_part > 0:
            binary_integer = str(integer_part % 2) + binary_integer
            integer_part = integer_part // 2

    # 转换小数部分为二进制
    binary_fractional = ""
    while fractional_part > 0:
        fractional_part *= 2
        bit = int(fractional_part)
        binary_fractional += str(bit)
        fractional_part -= bit
        if len(binary_fractional) > 12:
            break  # 限制小数部分的位数为12位

    binary = binary_integer
    if binary_fractional != "":
        binary += "." + binary_fractional

    return binary

冒泡排序(Python实现)

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。

原理

比较相邻的元素,如果第一个比第二个大,就交换。对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

时间复杂度

冒泡算法每次都需要对元素进行比较,是一种稳定的排序算法,时间复杂度为:O(n²)

Python实现

# -*- coding:utf-8 -*-
# 冒泡排序

'''
重点:每一轮比较都把最大的数放到最后,第二层循环的循环次数是递减的,
所以j终止的条件是 j = end - i - 1
'''

# while 写法
def bubble_sort(list):
    # if len(list) < 1:
    #     return list

    i = 0
    end = len(list) - 1
    while i < end:
        j = 0
        while j < end - i:
            if list[j] > list[j + 1]:
                list[j], list[j + 1] = list[j + 1], list[j]
            j = j + 1

        i = i + 1

    return list

# for 写法
def bubble_sort_for(list):
    # if len(list) < 1:
    #     return list

    end = len(list)

    # 外循环次数等于需排序个数减 1,比如3个数字,只需要循环两轮,i初始为0
    for i in range(end - 1):
        for j in range(end - i - 1): # 单趟排序比较的次数要减去已排序好的个数(即 i)
            if list[j] > list[j + 1]:
                list[j], list[j + 1] = list[j + 1], list[j]
    return list

快速排序(Python实现)

基本思想

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
下面这个图可以描述算法的实现过程:
快速排序

时间复杂度

快速排序是一种不稳定的排序方法,平均时间复杂度为O (nlogn),最坏情况和冒泡排序差不多,为O(n²)。

Python实现

# 简洁的实现方法
def quicksort(array):
  if len(array) < 2:
    return array
  else:
    pivot = array[0]
    less = [i for i in array[1:] if i <= pivot]
    greater = [i for i in array[1:] if i > pivot]
    return quicksort(less) + [pivot] + quicksort(greater)

print quicksort([10, 5, 2, 3]) # 结果:[2, 3, 5, 10]

# 比较容易理解的实现方法
def quick(list):
    if len(list) < 2:
        return list
    else:
        left = i = 0
        j = len(list) - 1
        
        while i != j:
            while list[j] >= list[left] and i < j:
                j -= 1

            while list[i] <= list[left] and i < j:
                i += 1
            
            if i < j:
                list[i], list[j] = list[j], list[i]
        list[i], list[left] = list[left],  list[i]
        return quick(list[left:i]) + [list[i]] + quick(list[i+1:])

注意理解:上面的第二种方法,挑选了左侧第一个数作为参考,内部循环则从对面,即列表末尾开始查找,因为如果从左侧开始查找,当满足条件i=j退出循环时,list[i]会比list[left]大,交换之后违反了左边小右边大的原则。

该实例中涉及Python的一个称作列表推导表达式的语法糖用法,即在for循环中嵌套使用if和else语句。例如:

oldList = [12, 3, 4, 6, 7, 13, 21]
newList = [x for x in oldList if x%2 == 0]
print newList # 结果:[12, 4, 6]
想了解更多Python语法糖知识,请参考:Python语法糖系列

python列表求和:循环实现与递归实现

循环实现:

def sum(arr):
  total = 0
  for x in arr:
    total += x
  return total

print sum([1, 2, 3, 4]) # 结果:10

递归实现:

def sum(arr):
  total = 0
  length = len(arr)
  if length == 0:
    return total
  else:
    return arr.pop(0) + sum(arr)
    
print sum([1,2]) # 结果:3