You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 03:33:19