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

如何编写可重复遍历列表直到h为0的Haskell函数inc_until?

Haskell实现inc_until函数:循环遍历列表直到h减为0

问题分析

你当前的代码仅能遍历输入列表一次,当列表遍历完成但h仍大于0时会直接终止,无法满足循环遍历直到h变为0的需求。要解决这个问题,需要引入辅助函数保存原始列表,当当前遍历的列表为空时,重新从原始列表开始遍历。

解决方案

实现思路

  1. 使用辅助函数携带原始列表作为参数,确保在当前遍历的列表耗尽时,能重新从原始列表开始循环。
  2. 当h减至0时,停止处理并返回结果。
  3. 遍历过程中,遇到偶数元素则加1并将h减1,否则直接保留元素并继续遍历。

修正后的代码

inc_until :: Integer -> [Integer] -> [Integer]
inc_until h xs = go h xs xs
  where
    -- 当h为0时,停止处理
    go 0 _ _ = []
    -- 当前列表遍历完,重新从原始列表开始
    go h orig [] = go h orig orig
    -- 处理当前元素
    go h orig (x:xs)
      | x `mod` 2 == 0 = (x + 1) : go (h - 1) orig xs
      | otherwise = x : go h orig xs

代码解释

  • 主函数inc_until调用辅助函数go,传入初始的h、当前遍历列表xs和原始列表xs。
  • 辅助函数go的第一个模式匹配处理h=0的终止条件,直接返回空列表。
  • 第二个模式匹配处理当前列表为空的情况,递归调用go并传入原始列表,实现循环遍历。
  • 第三个模式匹配处理单个元素:如果是偶数则加1并减少h,否则直接保留元素,继续遍历剩余列表。

针对测试用例的说明

你的测试用例inc_until 4 [1,2,3,4,5]期望返回[1,4,3,6,5],这意味着需求是对原始列表中的偶数元素累计加1次数(而非遍历修改后的列表)。如果是这种需求,需要调整实现逻辑:统计每个原始偶数元素被选中的次数,最终返回原始元素加上对应次数的结果。实现代码如下:

import Data.List (elemIndex)
import Data.Array (Array, listArray, (!), (//))

inc_until :: Integer -> [Integer] -> [Integer]
inc_until h xs = map (\x -> x + countArr ! idx) xs
  where
    len = length xs
    -- 生成循环的原始偶数元素索引序列
    evenIndices = cycle [i | (i, x) <- zip [0..] xs, x `mod` 2 == 0]
    -- 初始化计数数组,所有元素初始为0
    initArr = listArray (0, len-1) (replicate len 0) :: Array Int Int
    -- 统计前h次操作中每个索引被选中的次数
    countArr = foldr (\i arr -> arr // [(i, arr ! i + 1)]) initArr (take (fromIntegral h) evenIndices)
    -- 获取元素在原列表中的索引
    idx x = case elemIndex x xs of Just i -> i; _ -> 0

注意:此版本仅适用于有限列表,因为需要预先统计元素索引;如果要同时支持无限列表,建议采用第一种遍历序列的实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:47:03