haskell学习笔记(5)-函数与递归

任意循环结构都可以转化为递归,这就是haskell没有for while也可以实现任何应用的原因。

有些问题可以很容易的看出递归形式(如归并排序,快速排序),不过有的问题却不太容易(例如查找一组数中的最大值,统计数组的长度)。训练将任意问题都看成递归形式的能力,可以帮助我们更好的写出haskell代码,甚至是脱离了haskell之后,也可以使我们解决问题时多了一件工具。更好的理解一些比较复杂的算法(非常多的算法都是递归形式)。

以递归的观点看问题,就要将一个问题化解成一系列相似的小问题,同时要考虑到触底情况,递归的触底就是在某个限制条件触发时,递归函数不继续调用而直接返回,否则递归就会一直运行下去,直到爆栈为止。

haskell因为有模式匹配以及guards的存在,递归写法和一般语言不太一样,一开始会比较难理解语法。

求list的最大值

maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs

--等价的ruby常规写法
def max(arr)
  min=arr[0]
  arr.each do |item|
    if item>min
      min=item
    end
  end
  min
end

--等价的ruby递归写法
def max2(arr)
  #求arr[0~arr.length]的最大值,然后和arr[arr.length-1]比较
  _max2(arr,arr.length)
end

def _max2(arr, length)
  if length == 1
    return arr[0]
  end
  max=_max2(arr,length-1)
  if max>arr[length-1]
    return max
  else
    return arr[length-1]
  end
end
--可以看出,haskell即使是对比以简洁著称的ruby,他的递归代码量也非常少,所以他的语法结构是十分适合写递归函数的。

replicate 函数, 它取一个 Int 值和一个元素做参数, 返回一个包
含多个重复元素的 List, 如 replicate 3 5 返回 [5,5,5]

replicate' n x
| n <= 0 = []
| otherwise = x:replicate' (n-1) x

take 函数, 它可以从一个 List 取出一定数量的元素. 如
take 3 [5,4,3,2,1], 得 [5,4,3],注意他有两个触底情况

take' n _
| n <= 0 = []
take' _ [] = []
take' n (x:xs) = x : take' (n-1) xs

reverse 函数简单地反转一个 List

reverse' [] = []
reverse' (x:xs) = reverse' xs ++ [x]

查找

contain' a [] = False
contain' a (x:xs)
| a == x = True
| otherwise = contain' a xs 

快速排序(因为列表描述法的存在代码短的不可思议)
(不过这个需要额外的空间貌似,常规的快排是直接在单个数组的swap的,他这个是先分两个再合并)

quicksort [] = []
quicksort (x:xs) =
let smallerSorted = quicksort [a | a <- xs, a <= x]
biggerSorted = quicksort [a | a <- xs, a > x]
in smallerSorted ++ [x] ++ biggerSorted

欢迎关注我的github
https://github.com/luckyCatMiao

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值