Haskell学习笔记1

十道关于list列表的题

来源:

99 questions/1 to 10 - HaskellWiki

Hoogle

目录

1.找列表最后一个元素

2.找列表倒数第二个元素

3.找列表第k个元素

4.找列表有多少个元素

5.反转列表

6.找是不是回文 palindrome

7.展开嵌套列表

8.消除列表的重复元素

9.将列表中一样的元素分组

10.统计列表中每个元素的个数


找列表最后一个元素

最简单的方法就是反转列表然后再提取第一个元素

myLast' :: [a] -> a
myLast' = head . reverse

也可以用递归

myLast :: [a] -> a
myLast [] = error "No end for empty lists!"
myLast [x] = x
myLast (_:xs) = myLast xs

或者使用!!

myLast'' :: [a] -> a
myLast'' [] = error "No end for empty lists!"
myLast'' x = x !! (length x - 1)

!!的左边为列表,右边为整型数字

返回以右边数字为下标的在列表中的元素,比如

(!!) :: [a] -> Int -> a 
>>> ['a', 'b', 'c'] !! 0
'a'

2.找列表倒数第二个元素

两个简单的方法

myButLast,myButLast' :: [a] -> a

myButLast = last . init

myButLast' = head . reverse . init

第一个方法,先init,返回列表中除最后一个元素外的列表

然后使用last,返回列表最后一个元素,即原列表的倒数第二个元素

第二个方法,也先用init,返回列表中除最后一个元素外的列表

然后reverse反转列表,再head取出第一个元素,这个元素就是原列表的倒数第二个元素

找列表第k个元素

第一个方法,使用!!

elementAt :: [a] -> Int -> a
elementAt list i  = list !! (i-1)

这里要注意一点,因为!!使用的是下标,从0开始

然而问题问的是第k个元素,从1开始

所以!!的右边必须是i-1

第二个方法,递归

elementAt' :: [a] -> Int -> a
elementAt' (x:_) 1 = x --如果是第一个元素,直接返回
elementAt' (_:xs) i = elementAt' xs (i-1) --如果不是第一个元素,就从xs一个一个找
elementAt' _ _ = error "Index out of bounds" --没有index,错误

找列表有多少个元素

直接递归就可以了

myLength :: [a] -> Int 
myLength [] = 0 --空列表长度为0
myLength (_:xs) = 1 + myLength xs --每有一个元素就+1

也可以把列表所有的元素替换成1,然后sum

myLength' :: [a] -> Int 
myLength' = sum . map (\_->1)

反转列表

递归

myReverse :: [a] -> [a]
myReverse [] = [] --空列表直接返回空列表
myReverse (x:xs) = reverse xs ++ [x] --把x写入新的列表,然后递归剩下的元素

找是不是回文 palindrome

递归

isPalindrome :: (Eq a) => [a] -> Bool
isPalindrome xs = xs == (reverse xs) --直接判断跟不跟reverse过的相等

展开嵌套列表

例子:

λ> flatten (Elem 5)
[5]
λ> flatten (List [Elem 1, List [Elem 2, List [Elem 3, Elem 4], Elem 5]])
[1,2,3,4,5]
λ> flatten (List [])
[]

题目给的代码:

data NestedList a = Elem a | List [NestedList a]

递归,使用concatMap

concatMap例子

>>> concatMap (take 3) [[1..], [10..], [100..], [1000..]]
[1,2,3,10,11,12,100,101,102,1000,1001,1002]
flatten :: NestedList a -> [a]
flatten (Elem x) = [x] --如果是Elem,就直接返回
flatten (List x) = concatMap flatten x 

或者只使用最简单的递归

flatten' :: NestedList a -> [a]

flatten' (Elem a) = [a]
flatten' (List (x:xs)) = flatten x ++ flatten (List xs)
flatten' (List []) = []

消除列表的重复元素

最简单的方法,使用group关键字

注意,使用group必须先import Data.List

compress :: Eq a => [a] -> [a]
compress = map head . group

group例子

>>> group "Mississippi"
["M","i","ss","i","ss","i","pp","i"]

先group,然后提取每个group的head最后再map

将列表中一样的元素分组

使用span

pack (x:xs) = let (first,rest) = span (==x) xs
               in (x:first) : pack rest
pack [] = []

span会return两个列表,第一个列表是达到过滤条件的,第二个是除了第一个列表的所有元素

>>> span (< 3) [1,2,3,4,1,2,3,4]
([1,2],[3,4,1,2,3,4])

统计列表中每个元素的个数

使用group

encode,encode' :: Eq a => [a] -> [(Int, a)]

encode xs = map (\x -> (length x,head x)) (group xs)

encode' xs = [(length x, head x) | x <- group xs]
--encode'更容易理解一些,把xs group之后放入x
--x现在是比如 ["aaaa","bbbb","aa","cccc"]
--返回x的长度和x的第一个元素
--结果为[(4,'a'),(4,'b'),(2,'a'),(4,'c')]
λ> encode "aaaabccaadeeee"
[(4,'a'),(1,'b'),(2,'c'),(2,'a'),(1,'d'),(4,'e')]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值