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

未知整数范围增减性时,如何用单循环遍历且不交换索引?

单循环处理双向整数范围遍历

问题描述

我希望通过单个循环遍历某一整数范围,而非使用以下两个分支的for循环:

if (firstIndex <= secondIndex)
    for (int i = firstIndex; i <= secondIndex; i++)
    {...}
else
    for (int i = firstIndex; i >= secondIndex; i--)
    {...}

我曾考虑使用boost::irange,但它无法覆盖secondIndex索引。更新说明:我需要保留遍历顺序,且不能交换索引。

解决方案

方法一:计算步长实现单循环

直接通过步长统一循环逻辑,不需要分支判断,严格保留遍历顺序且不交换索引:

int start = firstIndex;
int end = secondIndex;
// 根据起始和终点的大小关系确定步长:正向为1,反向为-1
int step = (start <= end) ? 1 : -1;

// 循环条件根据步长动态判断,确保覆盖到end值
for (int i = start; 
     (step == 1) ? (i <= end) : (i >= end); 
     i += step)
{
    // 这里写你的循环处理逻辑
}

这个写法把两个分支的逻辑合并到了一个循环里,完全符合需求。

方法二:自定义范围类实现范围for(C++11+)

如果想让代码更优雅,适配范围for循环,可以封装一个简单的整数范围类:

#include <iterator>

struct IntRange {
    int start;
    int end;
    int step;

    struct Iterator {
        using iterator_category = std::input_iterator_tag;
        using value_type = int;
        using difference_type = int;
        using pointer = const int*;
        using reference = const int&;

        int current;
        int step;
        int end;

        Iterator(int curr, int s, int e) : current(curr), step(s), end(e) {}

        int operator*() const { return current; }
        Iterator& operator++() {
            current += step;
            return *this;
        }
        bool operator!=(const Iterator& other) const {
            // 根据步长判断是否还在遍历范围内
            return step > 0 ? (current <= other.end) : (current >= other.end);
        }
    };

    IntRange(int s, int e) 
        : start(s), end(e), step(s <= e ? 1 : -1) {}

    Iterator begin() const { return Iterator(start, step, end); }
    Iterator end() const { return Iterator(end + step, step, end); }
};

使用时直接用范围for,代码更简洁:

for (int i : IntRange(firstIndex, secondIndex)) {
    // 你的循环逻辑
}

关于boost::irange的补充

boost::irange默认是左闭右开区间,要包含secondIndex的话,需要根据方向调整终点参数:

#include <boost/range/irange.hpp>

if (firstIndex <= secondIndex) {
    for (int i : boost::irange(firstIndex, secondIndex + 1)) {
        // 逻辑
    }
} else {
    for (int i : boost::irange(firstIndex, secondIndex - 1, -1)) {
        // 逻辑
    }
}

但这种方式还是需要一次分支判断,不如前面的单循环方法直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:55:47