函数式编程实验2/华科

任务一

分析以下函数或表达式的类型(先自己分析再程序验证):

fun all (your, base) =  (*fn : int*string list->string list*)
	case your of
  		0 => base
      | _ => "are belong to us" :: all(your - 1, base)
      
fun funny (f, []) = 0				(*fn:(a'*int->int)*a' list->int*)
  | funny (f, x::xs) = f(x, funny(f, xs))
  
(fn x => (fn y => x)) "Hello, World!"
	(*fn : ?.X1 -> string*)

任务二

用归纳法证明ins函数和isort函数的正确性

fun ins (x, [ ]) = [x]
    | ins (x, y::L) = case compare(x, y) of
		       GREATER => y::ins(x, L)
		    |        _ 	  => x::y::L

简单归纳法,0个元素成立
k-1个元素成立=>k个元素成立

(*isort : int list -> int list*)
(* REQUIRES true 				*)
(* ENSURES isort(L) = a sorted perm of L 	*)

fun isort [ ] = [ ]
   |   isort (x::L) = ins (x, isort L)

简单归纳法,0个元素成立
k-1个元素成立=>k个元素成立

任务三

分析下面菲波拉契函数的执行性能

fun fib n = if n<=2 then 1 else fib(n-1) + fib(n-2);

准确的来说不是O(2n),详细看下方的链接中的证明
递推时间复杂度的求解

fun fibber (0: int) : int * int = (1, 1)
  | fibber (n: int) : int * int =
      let val (x: int, y: int) = fibber (n-1)
      in (y, x + y)
      end

O(n)

任务四

定义函数divisibleByThree: int -> bool,以使当n为3的倍数时,divisibleByThree n为true,否则为false。
注意:程序中不能使用取余函数’mod’。

(* divisibleByThree : int -> bool 	*)
(* REQUIRES: n>=0				*)
(* ENSURES: divisibleByThree n evaluates to true if n is a multiple of 3 and to false otherwise *)

fun divisibleByThree 0=true
	| divisibleByThree 1=false
	| divisibleByThree 2=false
	| divisibleByThree n=divisibleByThree (n-3);

任务五

函数evenP为偶数判断函数,即当且仅当该数为偶数时返回true。
其代码描述如下:
(* evenP : int -> bool )
(
REQUIRES: n >= 0 )
(
ENSURES: evenP n evaluates to true iff n is even. *)
fun evenP (0 : int) : bool = true
| evenP 1 = false
| evenP n = evenP (n - 2)
试编写奇数判断函数oddP: int -> bool,当且仅当该数为奇数时返回true。注意:代码不要调用函数evenP或mod。

fun oddP (0:int) :bool=false
	| oddP 1 =true
  | oddP n = oddP (n-2);

任务六

编写函数 interleave: int list * int list -> int list,该函数能实现两个int list数据的合并,且两个list中的元素在结果中交替出现,直至其中一个int list数据结束,而另一个int list数据中的剩余元素则直接附加至结果数据的尾部。如:
interleave([2],[4]) = [2,4]
interleave([2,3],[4,5]) = [2,4,3,5]
interleave([2,3],[4,5,6,7,8,9]) = [2,4,3,5,6,7,8,9]
interleave([2,3],[ ]) = [2,3]

fun interleave ([],B):int list=B
  | interleave (A,[])=A
  | interleave (x::A,y::B)=x::y::interleave(A,B);

任务七

编写函数reverse和reverse’,要求:
函数类型均为:int list->int list,功能均为实现输出表参数的逆序输出;
函数reverse不能借助任何帮助函数;函数reverse’可以借助帮助函数,时间复杂度为O(n)。

fun reverse []:int list=[]
	| reverse (x::L)=(reverse L)@[x]


fun reverseHelp ([],B):int list=B
	| reverseHelp (x::A,B)=reverseHelp(A,x::B);
fun reverse' L=reverseHelp(L,[]);

任务八

给定一个数组A[1…n],前缀和数组PrefixSum[1…n]定义为: PrefixSum[i] = A[0]+A[1]+…+A[i-1];
例如:PrefixSum [ ] = [ ]
PrefixSum [5,4,2] = [5, 9, 11]
PrefixSum [5,6,7,8] = [5,11,18,26]
试编写:
函数PrefixSum: int list -> int list,
要求:WPrefixSum(n) = O(n2)。(n为输入int list的长度)

fun PrefixSumHelp (x,[])=[ ]
	| PrefixSumHelp (x,a::L)=(x+a)::PrefixSumHelp(x,L);

fun PrefixSum []=[] 
	| PrefixSum (x::L)=x::PrefixSumHelp(x,PrefixSum L);

(2) 函数fastPrefixSum: int list -> int list,
要求: WfastPrefixSum(n) =O(n).
(提示:可借助帮助函数PrefixSumHelp)

fun PrefixSum []=[]   
	| PrefixSum [x]=[x]
	| PrefixSum (x::y::L)=x::PrefixSum(x+y::L); 

fun PrefixSumHelp ([],a):int list=[a] 
	| PrefixSumHelp (x::L,a)=a::PrefixSumHelp(L,a+x);
fun fastPrefixSum []=[]
	| fastPrefixSum (x::L)=PrefixSumHelp(L,x);
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值