能否将std::merge()与std::transform()合并为单次循环的原生实现?
解决方案:合并时同步完成大写转换
要避免两次遍历,可借助C标准库的迭代器机制或C20的ranges特性,在合并过程中同步完成字符串大写转换,以下是两种地道的实现方式:
方式一:自定义输出迭代器(兼容C++11及以上)
自定义一个输出迭代器,在元素写入目标容器时自动执行大写转换逻辑:
#include <vector> #include <algorithm> #include <string> #include <cctype> // 自定义输出迭代器,写入时将字符串转为大写 struct UppercaseOutputIter { using iterator_category = std::output_iterator_tag; using value_type = void; using difference_type = void; using pointer = void; using reference = void; explicit UppercaseOutputIter(std::vector<std::string>& dest) : dest_ptr(&dest) {} UppercaseOutputIter& operator=(const std::string& s) { std::string upper_str; upper_str.reserve(s.size()); std::transform(s.begin(), s.end(), std::back_inserter(upper_str), [](unsigned char c) { return std::toupper(c); }); dest_ptr->push_back(std::move(upper_str)); return *this; } UppercaseOutputIter& operator*() { return *this; } UppercaseOutputIter& operator++() { return *this; } UppercaseOutputIter operator++(int) { return *this; } private: std::vector<std::string>* dest_ptr; }; // 使用示例 int main() { const std::vector<std::string> vec1 = {"apple", "banana", "cherry"}; const std::vector<std::string> vec2 = {"date", "elderberry", "fig"}; std::vector<std::string> result; result.reserve(vec1.size() + vec2.size()); // 预分配空间避免多次扩容 std::merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), UppercaseOutputIter(result)); // result已包含有序且全大写的字符串 return 0; }
方式二:C++20 ranges链式调用(更简洁)
如果项目支持C++20,可结合std::ranges::merge和std::views::transform实现一行式的合并+转换:
#include <vector> #include <ranges> #include <algorithm> #include <string> #include <cctype> int main() { const std::vector<std::string> vec1 = {"apple", "banana", "cherry"}; const std::vector<std::string> vec2 = {"date", "elderberry", "fig"}; // 定义大写转换逻辑 auto to_upper = [](const std::string& s) { std::string upper_str; upper_str.reserve(s.size()); std::ranges::transform(s, std::back_inserter(upper_str), [](unsigned char c) { return std::toupper(c); }); return upper_str; }; // 合并视图并转换,最后存入vector auto merged_view = std::views::merge(vec1, vec2) | std::views::transform(to_upper); std::vector<std::string> result(merged_view.begin(), merged_view.end()); return 0; }
核心细节说明
- 两种方案均仅遍历一次元素,合并与转换同步完成,避免二次遍历的性能开销。
- 提前调用
reserve预分配目标容器空间,是提升性能的关键操作,可减少vector动态扩容的次数。 - 使用
std::toupper时传入unsigned char类型,避免处理部分编码下的负数值字符导致未定义行为。
内容的提问来源于stack exchange,提问作者codingnoob
相关产品推荐
相关产品推荐

