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

如何用C++ CUDA Thrust创建先偶后奇索引的迭代器?

若数组包含6个元素,该迭代器的索引序列应为[0, 2, 4, 1, 3, 5]。我了解counting_iterator和constant_iterator,但不知道如何创建上述迭代器,推测可能与transform_iterator有关,但具体实现方法不明。

嘿,这个需求确实可以用transform_iterator完美解决!核心思路就是用counting_iterator生成连续的基础索引(0到n-1),再通过一个自定义转换函数,把这些基础索引映射成你想要的「先偶后奇」序列。咱们一步步拆解实现:

核心转换逻辑

先明确转换规则:假设数组总共有n个元素,对于输入的基础索引i(范围0到n-1):

  • 当i在前半段(i < n/2)时,映射为偶数索引:2 * i
  • 当i在后半段(i >= n/2)时,映射为奇数索引:2 * (i - n/2) + 1

比如n=6时,前半段i=0、1、2 → 0、2、4;后半段i=3、4、5 → 1、3、5,正好匹配你的需求。

用Boost库实现(兼容C++11及以上)

如果你习惯用Boost的迭代器工具,代码可以这么写:

#include <iostream>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/transform_iterator.hpp>

// 定义转换函数对象,保存数组总大小
class EvenFirstMapper {
private:
    std::size_t total_size_;
public:
    explicit EvenFirstMapper(std::size_t size) : total_size_(size) {}

    std::size_t operator()(std::size_t idx) const {
        if (idx < total_size_ / 2) {
            return 2 * idx;
        } else {
            // 计算后半段对应的奇数索引
            return 2 * (idx - total_size_ / 2) + 1;
        }
    }
};

int main() {
    constexpr std::size_t arr_size = 6;
    
    // 创建转换迭代器:counting_iterator生成0~5,再通过EvenFirstMapper转换
    auto begin_iter = boost::make_transform_iterator(
        boost::counting_iterator<std::size_t>(0),
        EvenFirstMapper(arr_size)
    );
    auto end_iter = boost::make_transform_iterator(
        boost::counting_iterator<std::size_t>(arr_size),
        EvenFirstMapper(arr_size)
    );

    // 测试遍历
    for (auto it = begin_iter; it != end_iter; ++it) {
        std::cout << *it << " ";
    }
    // 输出:0 2 4 1 3 5
    return 0;
}

用C++20标准库实现(更简洁)

如果你的环境支持C++20,用标准库的std::counting_iterator和范围视图会更清爽,不需要额外依赖Boost:

#include <iostream>
#include <iterator>
#include <ranges>

int main() {
    constexpr std::size_t arr_size = 6;

    // 用lambda定义转换逻辑
    auto even_first_map = [n = arr_size](std::size_t idx) {
        return idx < n/2 ? 2*idx : 2*(idx - n/2) + 1;
    };

    // 生成索引序列:iota生成0~5,再通过transform转换
    auto even_first_indices = std::views::iota(0u, arr_size)
                              | std::views::transform(even_first_map);

    // 测试遍历
    for (auto idx : even_first_indices) {
        std::cout << idx << " ";
    }
    // 输出:0 2 4 1 3 5
    return 0;
}

额外说明

如果你只是需要遍历数组的偶索引再奇索引,也可以分开两次遍历,但用transform_iterator的好处是能得到一个单一的迭代器序列,可以直接传给需要迭代器范围的标准算法(比如std::copy、std::for_each),代码会更统一优雅。

内容的提问来源于stack exchange,提问作者Duke Le

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:58:01