策略是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换。
实例
Strategy.h
#ifndef STRATEGY_H_
#define STRATEGY_H_
#include <vector>
// 抽象策略类: 排序
class Sort {
public:
virtual void sortVector(std::vector<int> &arr) = 0;
};
#endif // STRATEGY_H_
ConcreteStrategy.h
#ifndef CONCRETE_STRATEGY_H_
#define CONCRETE_STRATEGY_H_
#include <vector>
#include <string>
#include <utility>
#include <iostream>
#include "Strategy.h"
// 打印vector内容
void printVector(const std::string prefix, const std::vector<int> &vi) {
std::cout << prefix;
for (auto i : vi) {
std::cout << " " << i;
}
std::cout << std::endl;
}
// 具体策略类: 冒泡排序
class BubbleSort : public Sort {
public:
void sortVector(std::vector<int> &vi) override {
printVector("冒泡排序前:", vi);
int len = vi.size();
// 轮次: 从1到n-1轮
for (int i = 0; i < len - 1; ++i) {
// 优化: 判断本轮是否有交换元素, 如果没交换则可直接退出
bool is_exchange = false;
for (int j = 0; j < len - i - 1; ++j) {
if (vi[j] > vi[j+1]) {
std::swap(vi[j], vi[j+1]);
is_exchange = true;
}
}
// 如果本轮无交换, 则可以直接退出
if (!is_exchange) {
printVector("冒泡排序后:", vi);
return;
}
}
printVector("冒泡排序后:", vi);
}
};
// 具体策略类: 选择排序
class SelectionSort : public Sort {
public:
void sortVector(std::vector<int> &vi) override {
printVector("选择排序前:", vi);
// 需要进行 n-1 轮
for (int i = 0; i < vi.size() - 1; ++i) {
// 找到此轮的最小值下标
int min_index = i;
for (int j = i + 1; j < vi.size(); ++j) {
if (vi[j] < vi[min_index]) {
min_index = j;
}
}
std::swap(vi[i], vi[min_index]);
}
printVector("选择排序后:", vi);
}
};
// 具体策略类: 插入排序
class InsertionSort : public Sort {
public:
void sortVector(std::vector<int> &vi) override {
printVector("插入排序前:", vi);
// 第一轮不需要操作, 第二轮比较一次, 第n轮比较 n-1 次
for (int i = 1; i < vi.size(); ++i) {
// 存储待插入的值和下标
int insert_value = vi[i];
int j = i - 1;
while (j >= 0 && vi[j] > insert_value) {
vi[j + 1] = vi[j]; // 如果左侧的已排序元素比目标值大, 那么右移
j--;
}
// 注意这里insert_index 需要+1
vi[j + 1] = insert_value;
}
printVector("插入排序后:", vi);
}
};
#endif // CONCRETE_STRATEGY_H_
Context.h
#ifndef CONTEXT_H_
#define CONTEXT_H_
#include <vector>
#include "Strategy.h"
class ArrayHandler {
public:
void sortVector(std::vector<int> &arr) {
return sort_->sortVector(arr);
}
void setSortStrategy(Sort* sort) {
sort_ = sort;
}
private:
Sort *sort_;
};
#endif // CONTEXT_H_
ArrayHandler是封装类,里面存具体的Sort算法。这样排序时调用的就是设置的具体Sort算法对象。
main.cpp
#include <vector>
#include <algorithm>
#include <random>
#include <iostream>
#include "ConcreteStrategy.h"
#include "Context.h"
std::vector<int> test_array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
int main() {
ArrayHandler array_handler;
{
// 冒泡排序
BubbleSort* bubble_sort = new BubbleSort();
auto rng = std::default_random_engine {};
std::shuffle(std::begin(test_array), std::end(test_array), rng);
array_handler.setSortStrategy(bubble_sort);
array_handler.sortVector(test_array);
delete bubble_sort;
}
{
// 选择排序
SelectionSort* select_sort = new SelectionSort();
auto rng = std::default_random_engine {};
std::shuffle(std::begin(test_array), std::end(test_array), rng);
array_handler.setSortStrategy(select_sort);
array_handler.sortVector(test_array);
delete select_sort;
}
{
// 插入排序
InsertionSort* insert_sort = new InsertionSort();
auto rng = std::default_random_engine {};
std::shuffle(std::begin(test_array), std::end(test_array), rng);
array_handler.setSortStrategy(insert_sort);
array_handler.sortVector(test_array);
delete insert_sort;
}
return 0;
}
编译运行:
$g++ -g main.cpp -o strategy -std=c++11
$./strategy
冒泡排序前: 19 21 5 6 12 4 13 20 1 22 11 14 18 2 24 23 9 10 16 3 7 17 15 25 8
冒泡排序后: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
选择排序前: 19 21 5 6 12 4 13 20 1 22 11 14 18 2 24 23 9 10 16 3 7 17 15 25 8
选择排序后: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
插入排序前: 19 21 5 6 12 4 13 20 1 22 11 14 18 2 24 23 9 10 16 3 7 17 15 25 8
插入排序后: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25