Haskell实现隔项选取素数列表的primeskip函数错误排查
修正Haskell的隔素数选取逻辑
你的核心问题是错误地用了固定步长的列表[2,5..]来筛选素数——素数的间隔没有固定规律,这种方式根本无法实现“隔一个素数选一个”的需求。正确的思路是先生成完整的素数序列,再从中每隔一个选取元素。
以下是两种可行的修正方案:
方案一:结合索引筛选
利用zip给每个素数分配索引,只保留索引为奇数的素数(即第1、3、5...个素数):
isPrime n = ip n [2..(n `div` 2)] where ip _ [] = True ip n (x:xs) | n `mod` x == 0 = False | otherwise = ip n xs primeskip :: Int -> [Int] primeskip n = take n [p | (idx, p) <- zip [1..] primes, odd idx] where primes = filter isPrime [2..]
方案二:递归跳过元素
定义一个递归函数直接遍历素数列表,每次取第一个元素并跳过第二个,效率更高:
isPrime n = ip n [2..(n `div` 2)] where ip _ [] = True ip n (x:xs) | n `mod` x == 0 = False | otherwise = ip n xs skipOne :: [Int] -> [Int] skipOne [] = [] skipOne (x:_:xs) = x : skipOne xs skipOne [x] = [x] primeskip :: Int -> [Int] primeskip n = take n $ skipOne primes where primes = filter isPrime [2..]
调用primeskip 10会返回你需要的结果:[2,5,11,17,23,31,41,47,59,67]
内容的提问来源于stack exchange,提问作者IdiotStump
相关产品推荐
相关产品推荐

