如何实现支持多容器的C++ shifter模板类?
实现思路
- 模板类设计:定义模板类
shifter<T>,模板参数T适配std::string、std::vector、std::deque等类数组容器,类内部持有该容器类型的私有成员存储数据。 - 移位逻辑处理:
- 边界防护:若容器为空,直接终止操作,避免无效计算。
- 步数归一化:当移位步数绝对值大于容器大小时,通过取模得到等效的实际移位步数(比如容器大小为4,右移5位等效于右移1位)。
- 移位实现:
- 正数右移:将容器末尾的
k个元素移至头部,借助std::rotate函数完成。 - 负数左移:转换为等效的右移步数(左移1位 = 右移
容器大小-1位),复用右移逻辑。
- 正数右移:将容器末尾的
- 复用标准库:依赖
<algorithm>中的std::rotate简化移位实现,无需手动遍历元素,保证代码简洁高效。
shifter.h 实现代码
#ifndef SHIFTER_H #define SHIFTER_H #include <algorithm> #include <string> #include <vector> #include <deque> template <typename T> class shifter { private: T data; public: // 构造函数,用传入的容器初始化内部数据 explicit shifter(T input) : data(std::move(input)) {} // 获取当前容器的常量引用,用于外部访问数据 const T& get_data() const { return data; } // 移位方法:正数右移,负数左移 void shift(int n) { if (data.empty()) { return; } const size_t size = data.size(); // 计算实际移位步数,处理步数超出容器大小的情况 int steps = n % static_cast<int>(size); if (steps < 0) { steps += static_cast<int>(size); } // 右移steps位:将最后steps个元素移到容器头部 auto start = data.begin(); auto mid = data.end() - steps; std::rotate(start, mid, data.end()); } }; #endif // SHIFTER_H
代码说明
- 构造函数:使用
std::move避免容器拷贝开销,explicit关键字防止隐式类型转换引发的意外。 - shift方法:
- 先判断容器是否为空,直接返回避免后续错误操作。
- 通过取模和正负转换,将所有移位需求统一为右移步数,简化逻辑。
std::rotate会把[mid, end)区间的元素移到[start, mid)前面,刚好实现右移效果。
- 兼容性:只要容器支持
begin()、end()、empty()、size()方法,且迭代器为随机访问类型(std::string、std::vector、std::deque均满足),即可正常使用。
测试示例(参考main函数用法)
#include "shifter.h" #include <iostream> int main() { // 测试vector右移 std::vector<int> vec = {1,2,3,4}; shifter<std::vector<int>> s_vec(vec); s_vec.shift(1); // 结果:4 1 2 3 for (int num : s_vec.get_data()) { std::cout << num << " "; } std::cout << std::endl; // 测试string左移 std::string str = "abcd"; shifter<std::string> s_str(str); s_str.shift(-1); // 结果:bcda std::cout << s_str.get_data() << std::endl; // 测试deque超步数移位 std::deque<char> dq = {'a','b','c','d','e'}; shifter<std::deque<char>> s_dq(dq); s_dq.shift(6); // 等效右移1位,结果:e a b c d for (char c : s_dq.get_data()) { std::cout << c << " "; } std::cout << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者Zelei Ádám István
相关产品推荐
相关产品推荐

