如何用递归与守卫生成指定区间内的完全平方数列表?
实现方案
首先可以复用你已经写好的isPerfectSquare函数,它能正确判断一个整数是否为完全平方数。接下来我们用递归+守卫实现支持双参数(起始值i和结束值n)的版本:
isPerfectSquare :: Integral a => a -> Bool isPerfectSquare n = sq * sq == n where sq = floor(sqrt(fromIntegral n :: Double)) squaresBetween :: Int -> Int -> [Int] squaresBetween i n | i > n = [] -- 递归终止:起始值超过结束值,返回空列表 | isPerfectSquare i = i : squaresBetween (i+1) n -- 当前数是完全平方数,加入列表后递归处理下一个数 | otherwise = squaresBetween (i+1) n -- 当前数不是,直接递归处理下一个数
逻辑说明
- 第一个守卫
i > n是递归的终止条件:当起始遍历的数已经超过结束值时,没有更多数需要检查,返回空列表。 - 第二个守卫判断当前的
i是否为完全平方数,如果是,就把i作为列表的第一个元素,接着递归调用squaresBetween (i+1) n获取后续的结果,用:拼接起来。 - 第三个分支(
otherwise)处理当前i不是完全平方数的情况,直接跳过,递归处理i+1到n的范围。
测试示例
调用squaresBetween 5 20会返回[9,16];调用squaresBetween 1 10则返回[1,4,9],和列表推导式的逻辑一致,只是改成了递归+守卫的实现方式。
内容的提问来源于stack exchange,提问作者Bailey
相关产品推荐
相关产品推荐

