常用算法实现
1. 快速排序(C++)
快速排序是一种高效的分治排序算法,平均时间复杂度为 O(n log n)。
#include <vector>
#include <algorithm>
template<typename T>
void quickSort(std::vector<T>& arr, int left, int right) {
if (left >= right) return;
// 选择中间元素作为基准
int pivot = arr[left + (right - left) / 2];
int i = left, j = right;
while (i <= j) {
while (arr[i] < pivot) i++;
while (arr[j] > pivot) j--;
if (i <= j) {
std::swap(arr[i], arr[j]);
i++;
j--;
}
}
if (left < j) quickSort(arr, left, j);
if (i < right) quickSort(arr, i, right);
}
// 使用示例
void example() {
std::vector<int> data = {64, 34, 25, 12, 22, 11, 90};
quickSort(data, 0, data.size() - 1);
}
2. 二分查找(Python)
在有序数组中快速查找目标元素,时间复杂度为 O(log n)。
def binary_search(arr, target):
"""二分查找算法"""
left, right = 0, len(arr) - 1
while left <= right:
mid = left + (right - left) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1 # 未找到
# 递归版本
def binary_search_recursive(arr, target, left=0, right=None):
if right is None:
right = len(arr) - 1
if left > right:
return -1
mid = left + (right - left) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
return binary_search_recursive(arr, target, mid + 1, right)
else:
return binary_search_recursive(arr, target, left, mid - 1)
# 查找插入位置
def search_insert_position(arr, target):
"""查找目标值应该插入的位置"""
left, right = 0, len(arr)
while left < right:
mid = left + (right - left) // 2
if arr[mid] < target:
left = mid + 1
else:
right = mid
return left
3. 动态规划 - 最长公共子序列(C++)
使用动态规划解决最长公共子序列问题。
#include <string>
#include <vector>
#include <algorithm>
int longestCommonSubsequence(const std::string& text1, const std::string& text2) {
int m = text1.length(), n = text2.length();
std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n + 1, 0));
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (text1[i-1] == text2[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
} else {
dp[i][j] = std::max(dp[i-1][j], dp[i][j-1]);
}
}
}
return dp[m][n];
}
// 获取实际的LCS字符串
std::string getLCS(const std::string& text1, const std::string& text2) {
int m = text1.length(), n = text2.length();
std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n + 1, 0));
// 构建DP表
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (text1[i-1] == text2[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
} else {
dp[i][j] = std::max(dp[i-1][j], dp[i][j-1]);
}
}
}
// 回溯构建LCS
std::string lcs;
int i = m, j = n;
while (i > 0 && j > 0) {
if (text1[i-1] == text2[j-1]) {
lcs = text1[i-1] + lcs;
i--; j--;
} else if (dp[i-1][j] > dp[i][j-1]) {
i--;
} else {
j--;
}
}
return lcs;
}
4. 图算法 - Dijkstra 最短路径(Python)
使用 Dijkstra 算法计算单源最短路径。
import heapq
from collections import defaultdict
class Graph:
def __init__(self):
self.graph = defaultdict(list)
def add_edge(self, u, v, weight):
"""添加有向边"""
self.graph[u].append((v, weight))
def dijkstra(self, start):
"""Dijkstra 最短路径算法"""
# 距离字典
distances = {node: float('inf') for node in self.graph}
distances[start] = 0
# 优先队列:(距离, 节点)
pq = [(0, start)]
visited = set()
# 前驱节点,用于重建路径
previous = {}
while pq:
current_dist, current_node = heapq.heappop(pq)
if current_node in visited:
continue
visited.add(current_node)
# 检查所有邻居
for neighbor, weight in self.graph[current_node]:
distance = current_dist + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
previous[neighbor] = current_node
heapq.heappush(pq, (distance, neighbor))
return distances, previous
def get_shortest_path(self, start, end):
"""获取从起点到终点的最短路径"""
distances, previous = self.dijkstra(start)
# 重建路径
path = []
current = end
while current in previous:
path.append(current)
current = previous[current]
path.append(start)
path.reverse()
return path, distances[end]
# 使用示例
g = Graph()
g.add_edge('A', 'B', 4)
g.add_edge('A', 'C', 2)
g.add_edge('B', 'C', 1)
g.add_edge('B', 'D', 5)
g.add_edge('C', 'D', 8)
path, dist = g.get_shortest_path('A', 'D')
print(f"最短路径: {' -> '.join(path)}, 距离: {dist}")
设计模式实现
1. 单例模式(C++)
确保一个类只有一个实例,并提供全局访问点。
#include <mutex>
#include <memory>
class Singleton {
private:
static std::unique_ptr<Singleton> instance;
static std::mutex mutex;
// 私有构造函数
Singleton() {}
public:
// 删除拷贝构造和赋值操作
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton& getInstance() {
std::lock_guard<std::mutex> lock(mutex);
if (!instance) {
instance.reset(new Singleton());
}
return *instance;
}
void doSomething() {
// 业务逻辑
}
};
// 静态成员初始化
std::unique_ptr<Singleton> Singleton::instance = nullptr;
std::mutex Singleton::mutex;
// C++11 线程安全版本(推荐)
class SingletonMeyers {
private:
SingletonMeyers() {}
public:
SingletonMeyers(const SingletonMeyers&) = delete;
SingletonMeyers& operator=(const SingletonMeyers&) = delete;
static SingletonMeyers& getInstance() {
static SingletonMeyers instance; // C++11保证线程安全
return instance;
}
};
2. 观察者模式(Python)
定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。
from abc import ABC, abstractmethod
from typing import List
class Observer(ABC):
"""观察者接口"""
@abstractmethod
def update(self, subject):
pass
class Subject:
"""主题/被观察者"""
def __init__(self):
self._observers: List[Observer] = []
self._state = None
def attach(self, observer: Observer):
"""添加观察者"""
if observer not in self._observers:
self._observers.append(observer)
def detach(self, observer: Observer):
"""移除观察者"""
if observer in self._observers:
self._observers.remove(observer)
def notify(self):
"""通知所有观察者"""
for observer in self._observers:
observer.update(self)
@property
def state(self):
return self._state
@state.setter
def state(self, value):
self._state = value
self.notify()
# 具体观察者
class ConcreteObserverA(Observer):
def update(self, subject):
print(f"ObserverA: 收到状态更新 - {subject.state}")
class ConcreteObserverB(Observer):
def update(self, subject):
print(f"ObserverB: 收到状态更新 - {subject.state}")
# 使用示例
subject = Subject()
observer_a = ConcreteObserverA()
observer_b = ConcreteObserverB()
subject.attach(observer_a)
subject.attach(observer_b)
subject.state = "新状态1"
subject.state = "新状态2"
3. 工厂模式(C++)
定义创建对象的接口,让子类决定实例化哪个类。
#include <memory>
#include <string>
// 产品接口
class Shape {
public:
virtual ~Shape() = default;
virtual void draw() const = 0;
virtual double area() const = 0;
};
// 具体产品
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() const override {
std::cout << "绘制圆形\n";
}
double area() const override {
return 3.14159 * radius * radius;
}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
void draw() const override {
std::cout << "绘制矩形\n";
}
double area() const override {
return width * height;
}
};
// 工厂类
class ShapeFactory {
public:
enum class ShapeType { CIRCLE, RECTANGLE };
static std::unique_ptr<Shape> createShape(ShapeType type,
double param1,
double param2 = 0) {
switch (type) {
case ShapeType::CIRCLE:
return std::make_unique<Circle>(param1);
case ShapeType::RECTANGLE:
return std::make_unique<Rectangle>(param1, param2);
default:
return nullptr;
}
}
};
// 使用
void factoryExample() {
auto circle = ShapeFactory::createShape(
ShapeFactory::ShapeType::CIRCLE, 5.0
);
circle->draw();
auto rect = ShapeFactory::createShape(
ShapeFactory::ShapeType::RECTANGLE, 4.0, 6.0
);
rect->draw();
}
4. 策略模式(Python)
定义一系列算法,将每个算法封装起来,使它们可以相互替换。
from abc import ABC, abstractmethod
class Strategy(ABC):
"""策略接口"""
@abstractmethod
def execute(self, data):
pass
class BubbleSortStrategy(Strategy):
"""冒泡排序策略"""
def execute(self, data):
arr = data.copy()
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
class QuickSortStrategy(Strategy):
"""快速排序策略"""
def execute(self, data):
if len(data) <= 1:
return data
pivot = data[len(data) // 2]
left = [x for x in data if x < pivot]
middle = [x for x in data if x == pivot]
right = [x for x in data if x > pivot]
return self.execute(left) + middle + self.execute(right)
class SortContext:
"""上下文类"""
def __init__(self, strategy: Strategy):
self._strategy = strategy
@property
def strategy(self):
return self._strategy
@strategy.setter
def strategy(self, strategy: Strategy):
self._strategy = strategy
def sort(self, data):
return self._strategy.execute(data)
# 使用示例
data = [64, 34, 25, 12, 22, 11, 90]
context = SortContext(BubbleSortStrategy())
result1 = context.sort(data)
print(f"冒泡排序: {result1}")
context.strategy = QuickSortStrategy()
result2 = context.sort(data)
print(f"快速排序: {result2}")
实用工具函数
1. 字符串处理工具(C++)
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
namespace StringUtils {
// 字符串分割
std::vector<std::string> split(const std::string& str, char delimiter) {
std::vector<std::string> tokens;
std::stringstream ss(str);
std::string token;
while (std::getline(ss, token, delimiter)) {
if (!token.empty()) {
tokens.push_back(token);
}
}
return tokens;
}
// 字符串trim
std::string trim(const std::string& str) {
auto start = std::find_if_not(str.begin(), str.end(),
[](unsigned char ch) { return std::isspace(ch); });
auto end = std::find_if_not(str.rbegin(), str.rend(),
[](unsigned char ch) { return std::isspace(ch); }).base();
return (start < end) ? std::string(start, end) : std::string();
}
// 字符串替换
std::string replace(std::string str, const std::string& from, const std::string& to) {
size_t pos = 0;
while ((pos = str.find(from, pos)) != std::string::npos) {
str.replace(pos, from.length(), to);
pos += to.length();
}
return str;
}
// 大小写转换
std::string toUpper(std::string str) {
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
return str;
}
std::string toLower(std::string str) {
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return str;
}
// 判断是否以某个前缀开始
bool startsWith(const std::string& str, const std::string& prefix) {
return str.size() >= prefix.size() &&
str.compare(0, prefix.size(), prefix) == 0;
}
// 判断是否以某个后缀结束
bool endsWith(const std::string& str, const std::string& suffix) {
return str.size() >= suffix.size() &&
str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}
} // namespace StringUtils
2. 文件操作工具(Python)
import os
import json
import csv
from pathlib import Path
from typing import List, Dict, Any
class FileUtils:
"""文件操作工具类"""
@staticmethod
def read_json(filepath: str) -> Dict[str, Any]:
"""读取 JSON 文件"""
with open(filepath, 'r', encoding='utf-8') as f:
return json.load(f)
@staticmethod
def write_json(filepath: str, data: Dict[str, Any], indent: int = 2):
"""写入 JSON 文件"""
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=indent, ensure_ascii=False)
@staticmethod
def read_csv(filepath: str) -> List[Dict[str, str]]:
"""读取 CSV 文件"""
with open(filepath, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
return list(reader)
@staticmethod
def write_csv(filepath: str, data: List[Dict[str, Any]],
fieldnames: List[str] = None):
"""写入 CSV 文件"""
if not data:
return
if fieldnames is None:
fieldnames = list(data[0].keys())
with open(filepath, 'w', encoding='utf-8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
@staticmethod
def ensure_dir(directory: str):
"""确保目录存在"""
Path(directory).mkdir(parents=True, exist_ok=True)
@staticmethod
def get_file_size(filepath: str) -> int:
"""获取文件大小(字节)"""
return os.path.getsize(filepath)
@staticmethod
def list_files(directory: str, extension: str = None) -> List[str]:
"""列出目录中的所有文件"""
path = Path(directory)
if extension:
return [str(f) for f in path.glob(f"*.{extension}")]
return [str(f) for f in path.glob("*") if f.is_file()]
@staticmethod
def copy_file(src: str, dst: str):
"""复制文件"""
import shutil
shutil.copy2(src, dst)
@staticmethod
def move_file(src: str, dst: str):
"""移动文件"""
import shutil
shutil.move(src, dst)
3. 日期时间工具(Python)
from datetime import datetime, timedelta
from typing import Optional
class DateTimeUtils:
"""日期时间工具类"""
@staticmethod
def now() -> datetime:
"""获取当前时间"""
return datetime.now()
@staticmethod
def format_datetime(dt: datetime, fmt: str = "%Y-%m-%d %H:%M:%S") -> str:
"""格式化日期时间"""
return dt.strftime(fmt)
@staticmethod
def parse_datetime(date_string: str, fmt: str = "%Y-%m-%d %H:%M:%S") -> datetime:
"""解析日期时间字符串"""
return datetime.strptime(date_string, fmt)
@staticmethod
def add_days(dt: datetime, days: int) -> datetime:
"""增加天数"""
return dt + timedelta(days=days)
@staticmethod
def add_hours(dt: datetime, hours: int) -> datetime:
"""增加小时"""
return dt + timedelta(hours=hours)
@staticmethod
def diff_days(dt1: datetime, dt2: datetime) -> int:
"""计算两个日期的天数差"""
return abs((dt2 - dt1).days)
@staticmethod
def is_weekend(dt: datetime) -> bool:
"""判断是否为周末"""
return dt.weekday() >= 5
@staticmethod
def get_month_range(year: int, month: int) -> tuple:
"""获取某月的开始和结束日期"""
start = datetime(year, month, 1)
if month == 12:
end = datetime(year + 1, 1, 1) - timedelta(days=1)
else:
end = datetime(year, month + 1, 1) - timedelta(days=1)
return start, end
@staticmethod
def timestamp_to_datetime(timestamp: float) -> datetime:
"""时间戳转日期时间"""
return datetime.fromtimestamp(timestamp)
@staticmethod
def datetime_to_timestamp(dt: datetime) -> float:
"""日期时间转时间戳"""
return dt.timestamp()
4. 数据验证工具(Python)
import re
from typing import Any
class ValidationUtils:
"""数据验证工具类"""
@staticmethod
def is_email(email: str) -> bool:
"""验证电子邮件格式"""
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
@staticmethod
def is_phone(phone: str) -> bool:
"""验证手机号码(中国)"""
pattern = r'^1[3-9]\d{9}$'
return bool(re.match(pattern, phone))
@staticmethod
def is_url(url: str) -> bool:
"""验证URL格式"""
pattern = r'^https?://[^\s/$.?#].[^\s]*$'
return bool(re.match(pattern, url))
@staticmethod
def is_ip_address(ip: str) -> bool:
"""验证IP地址"""
pattern = r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
return bool(re.match(pattern, ip))
@staticmethod
def is_strong_password(password: str) -> bool:
"""验证强密码(至少8位,包含大小写字母、数字和特殊字符)"""
if len(password) < 8:
return False
has_upper = bool(re.search(r'[A-Z]', password))
has_lower = bool(re.search(r'[a-z]', password))
has_digit = bool(re.search(r'\d', password))
has_special = bool(re.search(r'[!@#$%^&*(),.?":{}|<>]', password))
return all([has_upper, has_lower, has_digit, has_special])
@staticmethod
def is_number(value: Any) -> bool:
"""判断是否为数字"""
try:
float(value)
return True
except (ValueError, TypeError):
return False
@staticmethod
def is_positive_integer(value: Any) -> bool:
"""判断是否为正整数"""
try:
num = int(value)
return num > 0
except (ValueError, TypeError):
return False
@staticmethod
def sanitize_filename(filename: str) -> str:
"""清理文件名,移除非法字符"""
return re.sub(r'[<>:"/\\|?*]', '_', filename)
自定义数据结构
1. LRU 缓存(C++)
实现最近最少使用(Least Recently Used)缓存。
#include <unordered_map>
#include <list>
template<typename K, typename V>
class LRUCache {
private:
size_t capacity;
std::list<std::pair<K, V>> cache_list;
std::unordered_map<K, typename std::list<std::pair<K, V>>::iterator> cache_map;
public:
LRUCache(size_t cap) : capacity(cap) {}
V get(const K& key) {
auto it = cache_map.find(key);
if (it == cache_map.end()) {
throw std::runtime_error("Key not found");
}
// 移动到列表前端
cache_list.splice(cache_list.begin(), cache_list, it->second);
return it->second->second;
}
void put(const K& key, const V& value) {
auto it = cache_map.find(key);
if (it != cache_map.end()) {
// 更新已存在的键
it->second->second = value;
cache_list.splice(cache_list.begin(), cache_list, it->second);
} else {
// 添加新键
if (cache_list.size() == capacity) {
// 移除最久未使用的元素
auto last = cache_list.back();
cache_map.erase(last.first);
cache_list.pop_back();
}
cache_list.emplace_front(key, value);
cache_map[key] = cache_list.begin();
}
}
bool contains(const K& key) const {
return cache_map.find(key) != cache_map.end();
}
size_t size() const {
return cache_list.size();
}
};
2. 前缀树/字典树(Python)
高效存储和检索字符串集合的数据结构。
class TrieNode:
def __init__(self):
self.children = {}
self.is_end_of_word = False
self.word_count = 0
class Trie:
"""前缀树实现"""
def __init__(self):
self.root = TrieNode()
def insert(self, word: str):
"""插入单词"""
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end_of_word = True
node.word_count += 1
def search(self, word: str) -> bool:
"""搜索完整单词"""
node = self._find_node(word)
return node is not None and node.is_end_of_word
def starts_with(self, prefix: str) -> bool:
"""检查是否存在以prefix开头的单词"""
return self._find_node(prefix) is not None
def _find_node(self, prefix: str) -> TrieNode:
"""查找前缀对应的节点"""
node = self.root
for char in prefix:
if char not in node.children:
return None
node = node.children[char]
return node
def get_words_with_prefix(self, prefix: str) -> list:
"""获取所有以prefix开头的单词"""
node = self._find_node(prefix)
if node is None:
return []
words = []
self._dfs(node, prefix, words)
return words
def _dfs(self, node: TrieNode, current_word: str, words: list):
"""深度优先搜索收集单词"""
if node.is_end_of_word:
words.append(current_word)
for char, child_node in node.children.items():
self._dfs(child_node, current_word + char, words)
def delete(self, word: str) -> bool:
"""删除单词"""
def _delete(node, word, index):
if index == len(word):
if not node.is_end_of_word:
return False
node.is_end_of_word = False
return len(node.children) == 0
char = word[index]
if char not in node.children:
return False
should_delete = _delete(node.children[char], word, index + 1)
if should_delete:
del node.children[char]
return len(node.children) == 0 and not node.is_end_of_word
return False
return _delete(self.root, word, 0)
# 使用示例
trie = Trie()
words = ["apple", "app", "application", "apply", "banana"]
for word in words:
trie.insert(word)
print(trie.search("app")) # True
print(trie.starts_with("app")) # True
print(trie.get_words_with_prefix("app")) # ['app', 'apple', 'application', 'apply']