算法书中算法

时间:2022-07-25
本文章向大家介绍算法书中算法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

算法图解书中算法

二分查找

不断找出中值即可,判断所给值与中值的大小关系

def binary_search(num, target):
    low = 0
    high = len(num)-1
    while low <= high:
        mid = (low+high)//2
        guess = num[mid]
        if guess == target:
            return mid
        elif guess > target:
            high = mid-1
        else:
            low = mid+1
    return 


if __name__ == '__main__':
    print(binary_search([2, 3, 4, 5, 6, 7], 4))

快速排序

选择一个元素作为排序的基准值,然后将数组中小于该值的和大于该基准值的分别进行排序,不断递归该过程,最后将小于该基准值的数组、基准值、大于基准值的数组拼接为一个完整数据即可

def quick_sort(num):
    if (len(num) < 2):
        return num
    else:
        point = num[0]
        small = [i for i in num[1:] if i < point]
        large = [j for j in num[1:] if j > point]
    return quick_sort(small)+[point]+quick_sort(large)


if __name__ == '__main__':
    print(quick_sort([2, 4, 5, 3, 7]))

广度优先搜索

搜索图中是否还有某个节点

from collections import deque


graph = {}
graph["you"] = ["alice", "bob", "claire"]
graph["bob"] = ["anuj", "peggy"]
graph["alice"] = ["peggy"]
graph["claire"] = ["thom", "jonny"]
graph["anuj"] = []
graph["peggy"] = []
graph["thom"] = []
graph["jonny"] = []


def person_is_seller(name):
    return name[-1] == 'm'


def search(name):
    search_queue = deque()
    search_queue += graph[name]
    searched = []
    while search_queue:
        person = search_queue.popleft()
        if not person in searched:
            if person_is_seller(person):
                return True
            else:
                search_queue += graph[person]
                searched.append(person)
    return False

if __name__ == '__main__':
    print(search("you"))

## 狄克斯特拉算法 求图的最短路径

graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2

graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {} 


infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity


parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None

# 找出开销最低的节点
def find_lowest_cost_node(costs):
    lowest_cost = float("inf")
    lowest_cost_node = None
    # 遍历所有的节点
    for node in costs:
        cost = costs[node]
        # 如果当前节点的开销更低且未处理过
        if cost < lowest_cost and node not in processed:
            # 就将其视为开销最低的节点
            lowest_cost = cost
            lowest_cost_node = node
    return lowest_cost_node

# 在未处理的节点中找出开销最小的节点
node = find_lowest_cost_node(costs)
# 这个while循环在所有节点都被处理过后结束
while node is not None:
    cost = costs[node]
    neighbors = graph[node]
    # 遍历当前节点的所有邻居
    for n in neighbors.keys():
        new_cost = cost + neighbors[n]
        # 如果经当前节点前往该邻居更近
        if costs[n] > new_cost:
            # 就更新该邻居的开销
            costs[n] = new_cost
            # 同时将该邻居的父节点设置为当前节点
            parents[n] = node
    # 将当前节点标记为处理过
    processed.append(node)
    # 找出接下来要处理的节点,并循环
    node = find_lowest_cost_node(costs)

最长公共子串(序列)

动态规划解决,找出公式,先划出一个二维数组,

def find_lcsubstr(str_a, str_b):
    """
    最长公共子串
    """
    # 构造一个全为0的矩阵
    cell = [[0]*(len(str_a)+1)]*(len(str_b)+1)
    # 保存最长子串长度
    res = 0
    # 保存最后一相同字符的索引
    index = 0
    for i in range(len(str_a)):
        for j in range(len(str_b)):
            # 当字符相等
            if str_a[i] == str_b[j] :
                # 对第一个字符就相等的情况进行特殊处理
                if i==0 and j==0:
                    cell[i][j]=1
                # 将上次相同的值+1
                cell[i][j] = cell[i-1][j-1]+1
                # 计算保存最大值
                res = max(cell[i][j], res)
                # 将索引+1
                index = i+1
    # 返回长度和子串
    return res, str_a[index-res:res+1]


def find_lcseque(str_a, str_b):
    """
    最长公共子序列
    """
    # 构造一个全为0的矩阵
    cell = [[0]*(len(str_a)+1)]*(len(str_b)+1)
    # 保存子序列
    res = ''
    for i in range(len(str_a)):
        for j in range(len(str_b)):
            # 当字符相等
            if str_a[i] == str_b[j]:
                 # 对第一个字符就相等的情况进行特殊处理
                if i==0 and j==0:
                    cell[i][j]=1
                # 将上次相同的值+1
                cell[i][j] = cell[i-1][j-1] + 1
                # 将字符串累加
                res = res+str_a[i]
            else:
                # 对当前位置左边或者上面的最大值进行更新
                cell[i][j] = max(cell[i-1][j], cell[i][j-1])
    return res


if __name__ == '__main__':
    print(find_lcsubstr('vish', 'vishw'))
    print(find_lcseque('abdfg','abcdfg'))