当前位置: 首页 > news >正文

C语言实现策略模式

策略模式(Strategy Pattern)的核心是定义一系列算法,将每个算法封装起来,并使它们可以相互替换,从而让算法的变化独立于使用算法的客户端。在C语言中,可以通过函数指针(封装算法)+ 策略结构体(统一接口) 实现:客户端通过策略结构体调用不同算法,无需关心具体实现。

C语言实现策略模式的思路

  1. 策略接口(Strategy):定义算法的统一接口(函数指针结构体)。
  2. 具体策略(Concrete Strategy):实现策略接口,封装不同的算法逻辑。
  3. 上下文(Context):持有策略接口的指针,提供统一的接口供客户端调用,负责策略的切换。

示例:排序算法策略(多种排序算法可切换)

假设需要实现多种排序算法(冒泡排序、快速排序),客户端可根据场景动态选择排序策略,且无需修改排序调用逻辑。

步骤1:定义策略接口(排序算法接口)
#include <stdio.h>
#include <stdlib.h>// 策略接口:排序算法的统一接口
typedef struct SortStrategy {// 排序方法:参数为待排序数组、数组长度void (*sort)(int* arr, int length);
} SortStrategy;
步骤2:实现具体策略(不同排序算法)
2.1 冒泡排序策略
// 具体策略1:冒泡排序
static void bubble_sort(int* arr, int length) {printf("使用冒泡排序:\n");for (int i = 0; i < length - 1; i++) {for (int j = 0; j < length - i - 1; j++) {if (arr[j] > arr[j + 1]) {// 交换元素int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}// 初始化冒泡排序策略
SortStrategy* bubble_strategy_create() {static SortStrategy strategy; // 静态实例,避免动态分配strategy.sort = bubble_sort;return &strategy;
}
2.2 快速排序策略
// 快速排序辅助函数:分区
static int partition(int* arr, int low, int high) {int pivot = arr[high]; // 基准值int i = low - 1;       // 小于基准值的元素索引for (int j = low; j < high; j++) {if (arr[j] <= pivot) {i++;// 交换元素int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 交换基准值到正确位置int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;
}// 快速排序递归实现
static void quick_sort_recursive(int* arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high); // 分区索引quick_sort_recursive(arr, low, pi - 1);  // 左分区排序quick_sort_recursive(arr, pi + 1, high); // 右分区排序}
}// 具体策略2:快速排序(对外接口)
static void quick_sort(int* arr, int length) {printf("使用快速排序:\n");if (length <= 1) return;quick_sort_recursive(arr, 0, length - 1);
}// 初始化快速排序策略
SortStrategy* quick_strategy_create() {static SortStrategy strategy;strategy.sort = quick_sort;return &strategy;
}
步骤3:实现上下文(排序器,管理策略)

上下文持有策略指针,提供统一的排序接口,并支持动态切换策略。

// 上下文:排序器(使用策略的客户端)
typedef struct {SortStrategy* strategy; // 持有策略接口指针
} Sorter;// 初始化排序器(绑定初始策略)
void sorter_init(Sorter* sorter, SortStrategy* strategy) {sorter->strategy = strategy;
}// 切换策略
void sorter_set_strategy(Sorter* sorter, SortStrategy* strategy) {sorter->strategy = strategy;
}// 执行排序(通过策略接口调用具体算法)
void sorter_execute(Sorter* sorter, int* arr, int length) {if (sorter->strategy && arr && length > 0) {sorter->strategy->sort(arr, length); // 委托给策略执行}
}// 打印数组(辅助函数)
void print_array(int* arr, int length) {for (int i = 0; i < length; i++) {printf("%d ", arr[i]);}printf("\n");
}
步骤4:使用策略模式

客户端通过上下文切换不同策略,实现算法的灵活替换。

int main() {// 待排序数组int arr1[] = {5, 2, 9, 1, 5, 6};int length1 = sizeof(arr1) / sizeof(arr1[0]);int arr2[] = {3, 8, 7, 1, 2, 5, 4};int length2 = sizeof(arr2) / sizeof(arr2[0]);// 创建具体策略SortStrategy* bubble = bubble_strategy_create();SortStrategy* quick = quick_strategy_create();// 创建上下文(排序器)Sorter sorter;// 1. 使用冒泡排序sorter_init(&sorter, bubble);printf("排序前:");print_array(arr1, length1);sorter_execute(&sorter, arr1, length1);printf("排序后:");print_array(arr1, length1);// 2. 切换为快速排序printf("\n切换策略为快速排序:\n");printf("排序前:");print_array(arr2, length2);sorter_set_strategy(&sorter, quick);sorter_execute(&sorter, arr2, length2);printf("排序后:");print_array(arr2, length2);return 0;
}

输出结果

排序前:5 2 9 1 5 6 
使用冒泡排序:
排序后:1 2 5 5 6 9 切换策略为快速排序:
排序前:3 8 7 1 2 5 4 
使用快速排序:
排序后:1 2 3 4 5 7 8 

核心思想总结

  1. 算法封装与替换:每个算法(冒泡、快速排序)被封装为独立的策略,客户端通过切换策略指针实现算法替换,无需修改调用逻辑。
  2. 开放-封闭原则:新增排序算法(如插入排序)时,只需实现SortStrategy接口,无需修改上下文或其他策略代码。
  3. 消除条件判断:避免了用if-elseswitch判断选择算法的硬编码(如if (type == 1) 冒泡; else if (type == 2) 快速;),提高代码灵活性。

C语言通过函数指针直接封装算法,结合上下文管理策略,简洁地实现了策略模式的核心。这种模式适合处理“同一问题有多种解决方案,且需要动态选择”的场景(如支付方式、压缩算法、日志输出方式等)。

http://www.dtcms.com/a/564600.html

相关文章:

  • 微美全息(NASDAQ:WIMI)容错量子计算赋能,大规模机器学习模型高效量子算法获突破
  • 怎么通过贷款网站找做贷款客户wordpress主题支持分页
  • Linux网络编程核心实践:TCP/UDP socket与epoll高并发服务器构建
  • Kafka:专注高吞吐与实时流处理的分布式消息队列
  • 【基于one-loop-per-thread的高并发服务器】--- 项目介绍模块划分
  • 玩转Rust高级应用 如何于 `match` 分支模式之后的额外 `if` 条件,指定匹配守卫提供的额外条件
  • 太原理工大学头歌作业--2025数据结构实验一:顺序表
  • GNSS 高精度定位一体机的测试
  • Rust编程学习 - 如何学习有关函数和闭包的高级特性,这包括函数指针以及返回闭包
  • 学校建设网站前的市场分析网站可以不进行icp备案吗
  • MATLAB电力系统等值电路建模工具
  • C语言内功强化之函数
  • GAOXian_CAD_KURUICHENG
  • 【MRTK3踩坑记录】Unity 2022 中 MRTK3 Input Simulator 无法使用 WASD 控制相机的完整排查记录
  • 高校网站建设的意义流量网站建设教程
  • 布局具身智能赛道,深圳作为科技完成近亿元融资
  • 无zookeeper Kafka 4.1.0 Raft 集群搭建
  • 十五五规划产业布局正式落地,美尔斯通加速深耕量子科技
  • 解决glibc版本低VSCode无法远程问题
  • 线上编程哪家比较好阳西网站seo
  • 数据分析-数据沙箱
  • 【JUnit实战3_26】第十五章:表现层测试(下)—— Selenium 在网页测试中的用法
  • 浏览器——CSDN网站的页面就是打不开,显示无法访问的解决办法
  • 110、23种设计模式之状态模式(19/23)
  • 做一手楼盘的网站嵌入式工程师能干多久
  • Spring Boot 应用 Docker 监控:Prometheus + Grafana 全方位监控
  • git clone失败
  • Linux 命令与运维终极手册(2025 完整版)
  • 05-异常处理-导读
  • Pandas-之 数据聚合与分组