文章目录
动态规划(Dynamic Programming)
def knapsack(W, wt, val, n):
K = [[0 for w in range(W + 1)] for i in range(n + 1)]
# Build table K[][] in bottom up manner
for i in range(n + 1):
for w in range(W + 1):
if i == 0 or w == 0:
K[i][w] = 0
elif wt[i - 1] <= w:
K[i][w] = max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w])
else:
K[i][w] = K[i - 1][w]
return K[n][W]
# 测试数据
val = [60, 100, 120] # 物品价值
wt = [10, 20, 30] # 物品重量
W = 50 # 背包容量
n = len(val)
print(knapsack(W, wt, val, n)) # 输出:220
图算法(Graph Algorithms)
图算法有很多种,包括深度优先搜索(DFS)、广度优先搜索(BFS)、迪杰斯特拉算法(Dijkstra’s Algorithm)等。这里以深度优先搜索(DFS)为例:
# 使用邻接列表表示图
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
visited = set() # 设置一个集合来跟踪访问过的节点
def dfs(visited, graph, node):
if node not in visited:
print(node)
visited.add(node)
for neighbour in graph[node]:
dfs(visited, graph, neighbour)
# 测试DFS
dfs(visited, graph, 'A') # 从节点'A'开始DFS
深度优先搜索(DFS)
使用递归或栈来实现DFS。
# 使用邻接列表表示图
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E'],
}
visited = set() # 用来存储已访问的节点
def dfs(graph, start):
visited.add(start)
print(start, end=' ')
for next_node in graph[start]:
if next_node not in visited:
dfs(graph, next_node)
# 测试DFS
dfs(graph, 'A') # 从节点'A'开始DFS
广度优先搜索(BFS)
使用队列来实现BFS。
from collections import deque
# 使用邻接列表表示图
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E'],
}
def bfs(graph, root):
visited = set()
queue = deque([root])
while queue:
vertex = queue.popleft()
print(vertex, end=' ')
for neighbour in graph[vertex]:
if neighbour not in visited:
visited.add(neighbour)
queue.append(neighbour)
# 测试BFS
bfs(graph, 'A') # 从节点'A'开始BFS
字符串匹配算法 - KMP(Knuth-Morris-Pratt)算法
KMP算法是一种改进的字符串匹配算法,它可以在O(n+m)的时间复杂度内完成匹配,其中n和m分别是主串和模式串的长度。
def kmp_search(text, pattern):
def compute_prefix_function(pattern):
M, pi = len(pattern), [0] * len(pattern)
j = 0
for i in range(1, M):
while j > 0 and pattern[i] != pattern[j]:
j = pi[j - 1]
if pattern[i] == pattern[j]:
j += 1
pi[i] = j
return pi
def kmp_search_helper(text, pattern, pi):
N, M = len(text), len(pattern)
q = 0 # number of characters matched
for i in range(N):
while q > 0 and text[i] != pattern[q]:
q = pi[q - 1]
if text[i] == pattern[q]:
q += 1
if q == M:
return i - M + 1 # match found
return -1 # no match
pi = compute_prefix_function(pattern)
return kmp_search_helper(text, pattern, pi)
# 测试
text = "ABABDABACDABABCABAB"
pattern = "ABABCABAB"
print(kmp_search(text, pattern)) # 应该输出 6
下滑查看解决方法
### 字符串搜索算法 - 朴素字符串搜索朴素字符串搜索算法是最简单的字符串搜索算法,它通过逐个比较字符来查找模式串在主串中的位置。
def naive_search(text, pattern):
N, M = len(text), len(pattern)
for i in range(N - M + 1):
j = 0
while j < M and text[i + j] == pattern[j]:
j += 1
if j == M:
return i # 模式串被找到
return -1 # 模式串未找到
# 测试
text = "ABABDABACDABABCABAB"
pattern = "ABABCABAB"
print(naive_search(text, pattern)) # 应该输出 6
字符串编辑距离算法 - Levenshtein距离
Levenshtein距离(也称为编辑距离)是指两个字符串之间,由一个转换成另一个所需的最少单字符编辑操作次数。
def levenshtein_distance(s1, s2):
if len(s1) < len(s2):
return levenshtein_distance(s2, s1)
# len(s1) >= len(s2)
if len(s2) == 0:
return len(s1)
previous_row = range(len(s2) + 1)
for i, c1 in enumerate(s1):
current_row = [i + 1]
for j, c2 in enumerate(s2):
insertions = previous_row[j + 1] + 1
deletions = current_row[j] + 1
substitutions = previous_row[j] + (c1 != c2)
current_row.append(min(insertions, deletions, substitutions))
previous_row = current_row
return previous_row[-1]
# 测试
s1 = "kitten"
s2 = "sitting"
print(levenshtein_distance(s1, s2)) # 应该输出 3