热门角色不仅是灵感来源,更是你的效率助手。通过精挑细选的角色提示词,你可以快速生成高质量内容、提升创作灵感,并找到最契合你需求的解决方案。让创作更轻松,让价值更直接!
我们根据不同用户需求,持续更新角色库,让你总能找到合适的灵感入口。
本提示词可根据算法名称、功能目标及输入输出定义,自动生成多语言算法实现代码,并附实现思路说明。适用于算法学习、面试准备及项目开发,支持多语言选择与可直接运行的标准结构输出,帮助开发者快速验证算法逻辑、提高编程与复现效率。
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
import heapq
import math
import unittest
def dijkstra_shortest_path(
graph: Dict[Any, Iterable[Tuple[Any, Union[int, float]]]],
start: Any,
end: Optional[Any] = None,
return_path: bool = False,
):
"""
使用优先队列的 Dijkstra 最短路径算法。
参数:
graph: 字典,key 为节点(可哈希),value 为邻接列表 (邻居, 权重)。
示例: {"A":[("B",1.5),("C",2.0)], "B":[("C",1.0)]}
注意:无向图请提供双向边。
start: 起点(可哈希)
end: 终点(可选,None 表示计算到所有节点)
return_path: 若为 True:
- 当 end is None:返回 (distances, predecessors)
- 当 end is not None:返回 (distance, path)
返回:
- 如果 end is None:
- return_path=False -> dict[node] = 最短距离
- return_path=True -> (dict[node] = 最短距离, dict[node] = 前驱节点)
- 如果 end is not None:
- return_path=False -> distance: float(不可达为 math.inf)
- return_path=True -> (distance: float, path: list[节点];不可达为 (math.inf, []))
健壮性:
- 空图处理: 若图为空,仅返回与 start 相关的结果(到自身 0,其余不存在)
- 孤立顶点: 允许 start 不在图中,视为孤立点;若 end==start,距离为 0,否则不可达
- 校验:
- 节点需可哈希
- 权重需为非负且有限的数值
时间复杂度:
- O(E log V),其中 V 为顶点数,E 为边数(使用最小堆)
空间复杂度:
- O(V + E) 用于距离、前驱、邻接表和堆
"""
# ------------------------
# 输入校验与规范化
# ------------------------
if graph is None:
raise TypeError("graph 不能为 None,请提供字典形式的邻接表。")
if not isinstance(graph, dict):
raise TypeError("graph 必须为 dict[节点 -> 邻接列表]。")
# 校验并收集节点集;邻接表标准化为 dict[node] -> List[(neighbor, weight)]
adjacency: Dict[Any, List[Tuple[Any, float]]] = {}
nodes = set()
# 校验 start/end 可哈希
try:
hash(start)
except Exception as e:
raise TypeError(f"start 节点不可哈希: {start!r}") from e
if end is not None:
try:
hash(end)
except Exception as e:
raise TypeError(f"end 节点不可哈希: {end!r}") from e
for u, edges in graph.items():
# 校验节点可哈希
try:
hash(u)
except Exception as e:
raise TypeError(f"节点不可哈希: {u!r}") from e
nodes.add(u)
# 支持空/None 邻接列表(视为空)
if edges is None:
edges = []
# 校验邻接列表类型
if not isinstance(edges, (list, tuple)):
raise TypeError(f"节点 {u!r} 的邻接列表必须为 list/tuple[(邻居, 权重)]。")
normalized_edges: List[Tuple[Any, float]] = []
for item in edges:
if not isinstance(item, (list, tuple)) or len(item) != 2:
raise TypeError(f"邻接项需为 (neighbor, weight),收到: {item!r}")
v, w = item
try:
hash(v)
except Exception as e:
raise TypeError(f"邻居节点不可哈希: {v!r}") from e
# 权重校验:数值、有限、非负
if not isinstance(w, (int, float)):
raise TypeError(f"权重必须为数值 (int/float),收到: {w!r}")
if not math.isfinite(w):
raise ValueError(f"权重必须为有限数值,收到: {w!r}")
if w < 0:
raise ValueError(f"权重必须非负,收到: {w!r}")
nodes.add(v)
normalized_edges.append((v, float(w)))
adjacency[u] = normalized_edges
# 将 start/end 纳入节点集合(允许孤立点)
nodes.add(start)
if end is not None:
nodes.add(end)
# 确保每个节点在 adjacency 中有条目
for n in nodes:
adjacency.setdefault(n, [])
# ------------------------
# Dijkstra 主过程
# ------------------------
# 初始化距离与前驱
dist: Dict[Any, float] = {n: math.inf for n in nodes}
dist[start] = 0.0
prev: Dict[Any, Any] = {} # 记录最优前驱
# 小顶堆:(距离, 节点)
heap: List[Tuple[float, Any]] = [(0.0, start)]
# 若 end 指定,可提前终止:当 end 首次弹出且距离最小,即已确定最短路
target = end
while heap:
d_u, u = heapq.heappop(heap)
if d_u > dist[u]:
# 堆中旧条目,忽略
continue
if target is not None and u == target:
# 最短路径已确定,提前结束
break
# 松弛
for v, w in adjacency[u]:
nd = d_u + w
if nd < dist[v]:
dist[v] = nd
prev[v] = u
heapq.heappush(heap, (nd, v))
# ------------------------
# 构造返回值
# ------------------------
def reconstruct_path(predecessor: Dict[Any, Any], s: Any, t: Any) -> List[Any]:
if s == t:
return [s]
if dist.get(t, math.inf) == math.inf:
return []
path = []
cur = t
while cur != s:
path.append(cur)
cur = predecessor.get(cur)
if cur is None:
# 理论上不会发生;保护性处理
return []
path.append(s)
path.reverse()
return path
if end is None:
# 需求:返回到所有节点的最短距离;可选返回前驱表
return (dist, prev) if return_path else dist
else:
# 需求:返回到 end 的距离;可选返回路径
distance = dist.get(end, math.inf)
if return_path:
path = reconstruct_path(prev, start, end)
return (distance, path)
else:
return distance
# ------------------------
# 示例调用
# ------------------------
def _demo():
example_graph = {
"A": [("B", 1.5), ("C", 2.0)],
"B": [("C", 1.0)],
# 无向图示例:请提供双向边
# "C": [("A", 2.0), ("B", 1.0)]
}
print("示例:起点到所有节点的距离")
dist_all = dijkstra_shortest_path(example_graph, start="A", end=None, return_path=False)
print(dist_all) # {'A': 0.0, 'B': 1.5, 'C': 2.5}
print("示例:起点到终点的最短路与路径")
distance, path = dijkstra_shortest_path(example_graph, start="A", end="C", return_path=True)
print(distance, path) # 2.5 ['A', 'B', 'C']
# ------------------------
# 单元测试
# ------------------------
class TestDijkstraShortestPath(unittest.TestCase):
def test_directed_basic(self):
g = {
"A": [("B", 1.5), ("C", 2.0)],
"B": [("C", 1.0)],
}
distance, path = dijkstra_shortest_path(g, "A", "C", return_path=True)
self.assertEqual(distance, 2.5)
self.assertEqual(path, ["A", "B", "C"])
def test_all_distances(self):
g = {
"A": [("B", 2), ("C", 5)],
"B": [("C", 1)],
"C": [],
"D": [] # 孤立节点
}
dist = dijkstra_shortest_path(g, "A", end=None, return_path=False)
self.assertEqual(dist["A"], 0.0)
self.assertEqual(dist["B"], 2.0)
self.assertEqual(dist["C"], 3.0)
self.assertTrue(math.isinf(dist["D"]))
dist2, prev = dijkstra_shortest_path(g, "A", end=None, return_path=True)
self.assertEqual(dist2["C"], 3.0)
# 路径恢复 A->B->C
path_c = []
cur = "C"
while cur in prev:
path_c.append(cur)
cur = prev[cur]
path_c.append("A")
path_c.reverse()
self.assertEqual(path_c, ["A", "B", "C"])
def test_unreachable(self):
g = {
1: [(2, 1.0)],
2: [],
3: [] # 不可达
}
distance = dijkstra_shortest_path(g, 1, end=3, return_path=False)
self.assertTrue(math.isinf(distance))
distance, path = dijkstra_shortest_path(g, 1, end=3, return_path=True)
self.assertTrue(math.isinf(distance))
self.assertEqual(path, [])
def test_empty_graph(self):
g = {}
# 起点到自身为 0,其他不存在
dist = dijkstra_shortest_path(g, "S", end=None, return_path=False)
self.assertEqual(dist["S"], 0.0)
# 指定终点且不可达
d, p = dijkstra_shortest_path(g, "S", end="T", return_path=True)
self.assertTrue(math.isinf(d))
self.assertEqual(p, [])
def test_isolated_start(self):
g = {"A": [("B", 2.0)], "B": []}
# start 不在图中,视为孤立点
d = dijkstra_shortest_path(g, "Z", end=None, return_path=False)
self.assertEqual(d["Z"], 0.0)
self.assertTrue(math.isinf(d["A"]))
self.assertTrue(math.isinf(d["B"]))
# end==start
distance, path = dijkstra_shortest_path(g, "Z", end="Z", return_path=True)
self.assertEqual(distance, 0.0)
self.assertEqual(path, ["Z"])
def test_invalid_weight(self):
g_neg = {"A": [("B", -1.0)]}
with self.assertRaises(ValueError):
dijkstra_shortest_path(g_neg, "A", end=None)
g_inf = {"A": [("B", float("inf"))]}
with self.assertRaises(ValueError):
dijkstra_shortest_path(g_inf, "A", end=None)
def test_non_hashable_node(self):
g_bad = {["A"]: [("B", 1.0)]} # 列表不可哈希
with self.assertRaises(TypeError):
dijkstra_shortest_path(g_bad, "A", end=None)
if __name__ == "__main__":
_demo()
unittest.main(argv=["-v"], exit=False)
/**
* LRUCache - 基于双向链表 + Map 的 O(1) LRU 缓存
* 支持操作:get、put、clear、size
* 键:string | number
* 值:任意类型
*/
class LRUCache {
/**
* @param {number} capacity - 缓存容量,需为 > 0 的整数
*/
constructor(capacity) {
if (!Number.isInteger(capacity) || capacity <= 0) {
throw new Error('LRUCache: capacity must be an integer > 0');
}
this.capacity = capacity;
this.map = new Map(); // key -> node
// 伪头尾哨兵结点,便于O(1)在头/尾插入删除
this._head = { prev: null, next: null }; // 最近使用(MRU)在 head 之后
this._tail = { prev: null, next: null }; // 最久未使用(LRU)在 tail 之前
this._head.next = this._tail;
this._tail.prev = this._head;
}
/**
* 读取键的值,命中则移动至队首(MRU)
* @param {string|number} key
* @returns {*} 命中返回值,未命中返回 -1
*/
get(key) {
this._validateKey(key);
const node = this.map.get(key);
if (!node) return -1;
this._moveToHead(node);
return node.value;
}
/**
* 写入键值对,存在则更新并移动至队首;不存在则插入,满时淘汰LRU
* @param {string|number} key
* @param {*} value
* @returns {void}
*/
put(key, value) {
this._validateKey(key);
let node = this.map.get(key);
if (node) {
node.value = value;
this._moveToHead(node);
return;
}
// 需要新插入
if (this.map.size >= this.capacity) {
this._evictLRU();
}
node = { key, value, prev: null, next: null };
this.map.set(key, node);
this._addAfterHead(node);
}
/**
* 清空缓存
* @returns {void}
*/
clear() {
this.map.clear();
// 重置双向链表
this._head.next = this._tail;
this._tail.prev = this._head;
}
/**
* 当前元素数
* @returns {number}
*/
size() {
return this.map.size;
}
// ========== 内部私有工具方法(ES6下用下划线约定私有) ==========
_validateKey(key) {
const t = typeof key;
if (t !== 'string' && t !== 'number') {
throw new TypeError('LRUCache: key must be string or number');
}
}
_addAfterHead(node) {
// 插入到 head 之后 => 变为最新使用(MRU)
node.prev = this._head;
node.next = this._head.next;
this._head.next.prev = node;
this._head.next = node;
}
_removeNode(node) {
node.prev.next = node.next;
node.next.prev = node.prev;
node.prev = node.next = null;
}
_moveToHead(node) {
this._removeNode(node);
this._addAfterHead(node);
}
_evictLRU() {
// LRU在尾节点前一个
const lru = this._tail.prev;
if (lru === this._head) return; // 正常情况下不会发生
this._removeNode(lru);
this.map.delete(lru.key);
}
}
/************** 使用示例(可直接运行) **************/
(function demo() {
console.log('--- LRUCache Demo ---');
const cache = new LRUCache(2);
cache.put(1, 'A'); // 缓存: [1:A]
cache.put('b', 2); // 缓存: ['b':2, 1:'A'] (MRU在左侧)
console.log(cache.get(1)); // 命中A,移动到MRU => 输出: A
// 缓存: [1:'A', 'b':2]
cache.put(3, 'C'); // 容量满,淘汰LRU('b') -> 插入3
// 缓存: [3:'C', 1:'A']
console.log(cache.get('b')); // 未命中 => -1
console.log(cache.size()); // 2
cache.clear();
console.log(cache.size()); // 0
})();
TokenBucketLimiter(令牌桶限流器)
NewTokenBucketLimiter(capacity int, refillRate float64) -> *TokenBucketLimiter
(l *TokenBucketLimiter) Allow(n int) -> bool
(l *TokenBucketLimiter) Stop()
package main
import (
"fmt"
"math"
"sync"
"time"
)
// TokenBucketLimiter 是一个并发安全的令牌桶限流器。
// - capacity:桶容量(最大令牌数)
// - refillRate:令牌补充速率(个/秒)
// - tokens:当前桶内令牌数(可为浮点以承载分数累积)
// - lastRefill:上次补充时间
// - ticker:周期性触发补充的定时器
// - mu:互斥锁,保护 tokens/lastRefill 等共享状态
// - stopCh/stopOnce:优雅停止后台补充协程
type TokenBucketLimiter struct {
capacity float64
refillRate float64
mu sync.Mutex
tokens float64
lastRefill time.Time
ticker *time.Ticker
stopCh chan struct{}
stopOnce sync.Once
}
// 可调的后台补充粒度;无需与 refillRate 严格绑定,
// 我们使用“按实际流逝时间 * 速率”的方式补充,确保精度。
const defaultTick = 100 * time.Millisecond
// 防浮点误差
const epsilon = 1e-9
// NewTokenBucketLimiter 创建并启动一个令牌桶限流器。
// - capacity > 0,refillRate > 0,否则将触发 panic。
// - 初始为满桶,允许突发量为 capacity。
func NewTokenBucketLimiter(capacity int, refillRate float64) *TokenBucketLimiter {
if capacity <= 0 {
panic("TokenBucketLimiter: capacity must be > 0")
}
if refillRate <= 0 {
panic("TokenBucketLimiter: refillRate must be > 0")
}
l := &TokenBucketLimiter{
capacity: float64(capacity),
refillRate: refillRate,
tokens: float64(capacity), // 初始满桶
lastRefill: time.Now(),
ticker: time.NewTicker(defaultTick),
stopCh: make(chan struct{}),
}
// 后台补充协程:按实际 elapsed 计算补充量,精度不依赖 tick 粒度。
go l.refillLoop()
return l
}
// refillLoop 后台定时补充令牌。
func (l *TokenBucketLimiter) refillLoop() {
for {
select {
case <-l.ticker.C:
l.mu.Lock()
now := time.Now()
elapsed := now.Sub(l.lastRefill).Seconds()
if elapsed > 0 {
add := l.refillRate * elapsed
l.tokens = math.Min(l.capacity, l.tokens+add)
l.lastRefill = now
}
l.mu.Unlock()
case <-l.stopCh:
l.ticker.Stop()
return
}
}
}
// Allow 尝试消费 n 个令牌。
// 返回 true 表示通过并扣减令牌;否则返回 false。
// 并发安全。在调用时会做一次“按需补充”,进一步提高精度。
func (l *TokenBucketLimiter) Allow(n int) bool {
if n <= 0 {
return false
}
// 请求超过桶容量,永远无法满足,直接拒绝。
if float64(n) > l.capacity {
return false
}
l.mu.Lock()
defer l.mu.Unlock()
// 按需补充:基于最后一次补充时间与当前时间计算新增令牌。
now := time.Now()
elapsed := now.Sub(l.lastRefill).Seconds()
if elapsed > 0 {
add := l.refillRate * elapsed
l.tokens = math.Min(l.capacity, l.tokens+add)
l.lastRefill = now
}
if l.tokens+epsilon >= float64(n) {
l.tokens -= float64(n)
return true
}
return false
}
// Stop 停止后台 ticker 并释放资源;可重复调用且并发安全。
func (l *TokenBucketLimiter) Stop() {
l.stopOnce.Do(func() {
close(l.stopCh)
})
}
// 以下为使用示例
func main() {
// 桶容量 5,每秒补充 10 个令牌
limiter := NewTokenBucketLimiter(5, 10.0)
defer limiter.Stop()
var wg sync.WaitGroup
// 并发模拟 20 次请求,单次消耗 1 个令牌
fmt.Println("First burst:")
wg.Add(20)
for i := 0; i < 20; i++ {
go func(id int) {
defer wg.Done()
if limiter.Allow(1) {
fmt.Printf("req %02d: allowed\n", id)
} else {
fmt.Printf("req %02d: rejected\n", id)
}
}(i)
}
wg.Wait()
// 等待 500ms,让令牌部分补充(约 5 个)
time.Sleep(500 * time.Millisecond)
fmt.Println("Second burst after 500ms:")
wg.Add(10)
for i := 0; i < 10; i++ {
go func(id int) {
defer wg.Done()
if limiter.Allow(1) {
fmt.Printf("req2-%02d: allowed\n", id)
} else {
fmt.Printf("req2-%02d: rejected\n", id)
}
}(i)
}
wg.Wait()
}
帮助用户快速生成符合业务需求的算法代码及其实现说明,满足开发、学习或项目需求的场景,提升开发效率和知识掌握。
帮助算法工程师快速从需求到代码,节省开发时间,专注于核心算法优化
辅助编程入门者从零生成完整代码,陪伴他们逐步理解算法实现逻辑
支持教学使用,可用于算法设计课程展示与学生实践练习,加深其理解
将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。
把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。
在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。
半价获取高级提示词-优惠即将到期