在Haskell中加倍列表(列表中的数字)

  • 本文关键字:列表 数字 Haskell haskell
  • 更新时间 :
  • 英文 :


其他人能在Haskell中这样编码吗:数字翻倍数字需要加倍,为此可以定义以下功能:

doubleDigits :: [Integer] -> [Integer]

函数doubleDigits必须从右边开始每隔一个数字加倍。倒数第二个数字先加倍,然后倒数第四个。。。,等等

Input: doubleDigits [1,2,3,4,5,6,7]
Output: [1,4,3,8,5,12,7]
toDigitsReverse :: Integer -> [Integer]
toDigitsReverse n = reverse (toDigits n)
-- function to help double every other element of list
doubleDigitsHelper :: [Integer] -> Integer -> [Integer]
doubleDigitsHelper l t
| l == [] = []
| t == 0 = [head l] ++ (doubleDigitsHelper (drop 1 l) 1)
| t == 1 = [2*(head l)] ++ (doubleDigitsHelper (drop 1 l) 0)
-- function to double every other element
doubleDigits :: [Integer] -> [Integer]
doubleDigits l = reverse (doubleDigitsHelper (reverse l) 0)

另一种方法:

让我们zip列表中的元素及其索引。

[1,2,3,4,5,6,7] `zip` [0..]

我们得到:

[(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6)]

然后我们可以map这个到想要的结果:

let f (x, i) = if even i then x else x * 2 in map f $ [1,2,3,4,5,6,7] `zip` [0..]

结果是:

[1,4,3,8,5,12,7]

或者写得有点不同:

doubleDigits lst = map f lst'
where
lst' = lst `zip` [0..]
f (x, i)
| even i = x
| otherwise = x * 2

因为您想从右侧开始将其他元素加倍,所以您可以简单地反转列表,用索引压缩它,映射,然后保留输出。

doubleDigits lst = reverse $ map f lst'
where
lst' = (reverse lst) `zip` [0..]
f (x, i)
| even i = x
| otherwise = x * 2

我想说的是,首先reverse列表没有意义,确定累加器(t)是偶数还是奇数(有内置的函数用于此,例如even),然后采取相应的行动。接下来可以改进代码的是使用模式匹配,而不是==head/tail调用。此外,我还更改了助手函数的顺序:

-- function to help double every other element of list
doubleDigitsHelper :: Integer -> [Integer] -> [Integer]
doubleDigitsHelper _ [] = []
doubleDigitsHelper t (x:xs) | even t  = x : doubleDigitsHelper (t+1) xs 
| otherwise = 2*x : doubleDigitsHelper (t+1) xs

-- function to double every other element
doubleDigits :: [Integer] -> [Integer]
doubleDigits = doubleDigitsHelper 0

您可以将要应用的交替函数放在列表(cycle [id, (*2)])中,并使用zipWith将这些函数应用于您的列表。

doubleDigits :: Num a => [a] -> [a]
doubleDigits = reverse . zipWith ($) (cycle [id, (*2)]) . reverse

如果你想从右边开始交替,我看不出有什么优雅的方法可以扭转列表。例如,您可以先查看列表的长度,然后在此基础上更改函数的顺序,但这会使函数稍微复杂一些。

doubleDigits xs = zipWith ($) fs xs
where fs = (if even . length $ xs then tail else id) $ cycle [id, (*2)]

相关内容

  • 没有找到相关文章

最新更新