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

如何实现逆序生成偶数的Rust Iterator?修正反向步长异常

问题描述

我希望创建一个能从指定值开始逆序生成偶数的Iterator。以下Rust程序演示了当前存在的问题:该程序从命令行读取两个整数,输出它们之间的降序偶数(假设最小值为偶数)。

原代码:

use std::io::{self, BufRead};
fn main() {
    // Read numbers
    let mut input = io::BufReader::new(io::stdin());
    let mut buf = String::new();
    input.read_line(&mut buf).unwrap();

    let mut split = buf.split(" ");
    let min = split.next().unwrap().trim().parse::<i64>().unwrap();
    let max = split.next().unwrap().trim().parse::<i64>().unwrap();
    // Attempt to generate the iterator
    let payload: String = (min..max)
        .rev()
        .step_by(2)
        .map(|x| x.to_string() + " ")
        .collect();
    println!("{payload}");
}

当输入2 6时,程序输出5 3,而预期结果应为4 2(正序迭代可生成2 4)。请问如何实现能得到正确结果的Iterator?


问题分析与解决方案

原因分析

原代码的核心问题在于左闭右开区间的逆序逻辑:

  • 正序时2..6生成的是2,3,4,5,过滤偶数后得到2,4,符合预期。
  • 调用.rev()后,区间会逆转为5,4,3,2,再通过.step_by(2)取数时,会从5开始每隔2个取一个,最终得到5,3,完全偏离了目标偶数序列。

可行解决方案

方法1:调整区间起点,生成正确的逆序偶数序列

先计算区间内最大的有效偶数(因为max是开区间,实际上限是max-1,如果是奇数则减1转为偶数,偶数直接使用),再基于调整后的区间生成逆序序列:

use std::io::{self, BufRead};
fn main() {
    let mut input = io::BufReader::new(io::stdin());
    let mut buf = String::new();
    input.read_line(&mut buf).unwrap();

    let mut split = buf.split(" ");
    let min = split.next().unwrap().trim().parse::<i64>().unwrap();
    let max = split.next().unwrap().trim().parse::<i64>().unwrap();
    
    // 计算区间内最大的偶数
    let max_even = if (max - 1) % 2 == 0 { max - 1 } else { max - 2 };
    let payload: String = (min..=max_even)
        .rev()
        .step_by(2)
        .map(|x| format!("{x} "))
        .collect();
    println!("{payload}");
}

方法2:先过滤偶数再逆序(简单直观)

先在正序区间中过滤出所有偶数,再将结果逆序,这种方法逻辑简单易懂,适合快速实现:

use std::io::{self, BufRead};
fn main() {
    let mut input = io::BufReader::new(io::stdin());
    let mut buf = String::new();
    input.read_line(&mut buf).unwrap();

    let mut split = buf.split(" ");
    let min = split.next().unwrap().trim().parse::<i64>().unwrap();
    let max = split.next().unwrap().trim().parse::<i64>().unwrap();
    
    let payload: String = (min..max)
        .filter(|&x| x % 2 == 0)
        .rev()
        .map(|x| format!("{x} "))
        .collect();
    println!("{payload}");
}

方法3:手动实现逆序偶数迭代器(自定义逻辑)

如果需要更灵活的控制,可以手动实现一个符合需求的Iterator,这种方式适合需要复用该迭代逻辑的场景:

use std::io::{self, BufRead};
use std::iter::Iterator;

// 自定义逆序偶数迭代器
struct DescendingEven {
    current: i64,
    min: i64,
}

impl Iterator for DescendingEven {
    type Item = i64;
    fn next(&mut self) -> Option<Self::Item> {
        if self.current < self.min {
            None
        } else {
            let result = self.current;
            self.current -= 2;
            Some(result)
        }
    }
}

// 生成迭代器的构造函数
fn descending_even(min: i64, max: i64) -> DescendingEven {
    let start = if (max - 1) % 2 == 0 { max - 1 } else { max - 2 };
    DescendingEven { current: start, min }
}

fn main() {
    let mut input = io::BufReader::new(io::stdin());
    let mut buf = String::new();
    input.read_line(&mut buf).unwrap();

    let mut split = buf.split(" ");
    let min = split.next().unwrap().trim().parse::<i64>().unwrap();
    let max = split.next().unwrap().trim().parse::<i64>().unwrap();
    
    let payload: String = descending_even(min, max)
        .map(|x| format!("{x} "))
        .collect();
    println!("{payload}");
}

验证结果

以上三种方法在输入2 6时,都会输出4 2,完全符合预期。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:37:35