SML / NJ的简单功能

时间:2013-10-12 03:16:10

标签: functional-programming sml smlnj

我被要求为课堂上的问题编写一组函数。我认为我写它们的方式比它们需要的要复杂一些。我必须自己实现所有功能,而不使用和预定义的功能。我想知道这些答案中是否有任何简单的“一线”版本?

  
      
  1. 集合可以表示为列表。集合的成员可以按列表中的任何顺序出现,但不应超过一个   在列表上出现一个元素。
  2.         

    (a)将dif(A,B)定义为   计算A和B的集合差异,A-B。

         

    (b)定义笛卡儿(A,   B)计算集合A的笛卡尔积和集合B,{(a,b)|   a∈A,b∈B}。

         

    (c)考虑数学感应证明   如下:如果集合A有n个元素,那么A的powerset有2n   元素。在证明之后,定义powerset(A)来计算   集A的幂集,{B | B⊆A}。

         

    (d)定义给定的函数   集合A和自然数k,返回所有子集的集合   A大小为k。

(* Takes in an element and a list and compares to see if element is in list*)

fun helperMem(x,[]) = false
|   helperMem(x,n::y) =
      if x=n then true
      else helperMem(x,y);

(* Takes in two lists and gives back a single list containing unique elements of each*)

fun helperUnion([],y) = y
|   helperUnion(a::x,y) =
       if helperMem(a,y) then helperUnion(x,y)
       else a::helperUnion(x,y);

(* Takes in an element and a list. Attaches new element to list or list of lists*)
 fun helperAttach(a,[]) = []
  helperAttach(a,b::y) = helperUnion([a],b)::helperAttach(a,y);


  (* Problem 1-a *)
fun myDifference([],y) = []
 |   myDifference(a::x,y) = 
    if helper(a,y) then myDifference(x,y)
    else a::myDifference(x,y);

 (* Problem 1-b *)
 fun myCartesian(xs, ys) =
    let fun first(x,[]) = []
    |       first(x, y::ys) = (x,y)::first(x,ys)
        fun second([], ys) = []
    |       second(x::xs, ys) = first(x, ys) @ second(xs,ys)
    in      second(xs,ys) 
    end;


 (* Problem 1-c *)
 fun power([]) = [[]]
 |   power(a::y) = union(power(y),insert(a,power(y)));

我从来没有遇到问题1-d,因为这些花了我一段时间才得到。有关削减这些更短的建议吗?还有一个我没有得到的问题,但我想知道如何解决它以供将来的测试。

  
      
  1. (楼梯问题)你想上n(> 0)步的楼梯。有一段时间,您可以一步,两步或三步。但,   例如,如果还剩下一步,你只能去一个   一步,而不是两三步。有多少不同的方式   走上楼梯?用sml解决这个问题。 (a)解决它   递归。 (b)迭代解决。
  2.   

有关如何解决此问题的任何帮助?

1 个答案:

答案 0 :(得分:2)

你的设定功能看起来不错。除了他们的格式和命名之外,我不会改变他们的任何主要内容:

fun member (x, [])    = false
  | member (x, y::ys) = x = y orelse member (x, ys)

fun dif ([],   B) = []
  | dif (a::A, B) = if member (a, B) then dif (A, B) else a::dif(A, B)

fun union ([],   B) = B
  | union (a::A, B) = if member (a, B) then union (A, B) else a::union(A, B)

(* Your cartesian looks nice as it is. Here is how you could do it using map: *)
local val concat = List.concat
      val map = List.map
in fun cartesian (A, B) = concat (map (fn a => map (fn b => (a,b)) B) A) end

你的力量也非常整洁。如果你调用你的函数insert,它应该有关于在许多列表中插入内容的注释。也许insertEach或类似名称更好。

在您的上一个任务中,由于这是一个计数问题,您不需要生成实际的步骤组合(例如,作为步骤列表),只计算它们。使用递归方法,尝试将基本案例写入问题描述中。

即,创建一个函数steps : int -> int,其中预先计算采用0,1和2步的方法的数量,但对于 n 步, n> 2 ,您知道有一组以1,2或3步开始的步骤组合加上 n-1 n-2的数字组合分别是 n-3 步骤。

使用迭代方法,从底部开始并使用参数化计数变量。 (对不起,这里有模糊的提示。)