列表操作的数据类型

时间:2015-10-15 13:58:11

标签: sml type-conversion smlnj

我有这个问题需要解决enter image description here

我已经设法解决了它但没有该函数execute_ops。这是我的解决方案:

datatype list_op = insert of int*int | delete of int | setsize of int;

exception wrong_case;

fun insert(x,pos,nil) = [x]
  | insert(x,pos,h::t) = if (pos=h) then x::h::t else h::insert(x,pos,t);

fun setsize(0) = nil
  | setsize(1) = [0]
  | setsize(n) = 0 :: setsize(n-1);

fun delete (l,0) = l
  | delete (nil,_) = raise wrong_case
  | delete (h::t,n) = if n = h then h::t else delete(t,n-1);

insert(3, 4, delete(setsize(5), 3));

首先我不确定我的解决方案是否正确,因为我不明白setize是什么。

如何以正确的方式编写代码?

谢谢

1 个答案:

答案 0 :(得分:1)

因此,对于这三个操作中的每一个,您似乎已经定义了 helper 函数,这些函数执行操作背后的逻辑。除了修复这个逻辑以便工作之外,剩下的就是将这些函数拼凑在一起形成函数execute_ops

  1. 如果这些值同时是数据类型的值构造函数,则不得将函数命名为insertdeletesetsize。简单地说,一旦定义了数据类型,然后定义了同一范围内的函数,函数就会遮蔽值构造函数,并使您无法表达 list_op 类型的值。

    重要的,我怀疑令人困惑的一点是,insertdeletesetsize不是在列表上执行操作的函数。它们是值构造函数,很像leafnode用于创建二叉树:

    datatype tree = leaf | node of tree*int*tree
    
  2. 比较pos=h中的insert没有意义。列表中的元素与其位置不同。您希望在位置 pos处插入x,而不是在等于 pos的第一个元素处插入x。值不一定等于它在列表中的位置。

  3. 遗憾的是delete完全没有意义;您的代码所说的是"如果数字n等于列表中的元素,则返回整个列表。否则,删除元素并继续删除元素,直到这种情况,或者列表为空。"

    根据定义,也不需要在delete中提出异常。

  4. 我不明白你不懂什么是什么意思。它应该是一个设置列表大小的操作。重复分配文本,如果大小小于当前长度,则删除多余的元素,否则用零扩展列表的末尾。

  5. 以下是解决作业的模板:

    datatype list_op = insert of int*int | delete of int | setsize of int
    
    fun insert_h (0, elem, x::xs) = ...   (* insert elem instead of x *)
      | insert_h (pos, elem, []) = ...    (* list was too short *)
      | insert_h (pos, elem, x::xs) = ... (* not there yet *)
    
    fun setsize_h (0, xs) = ...           (* wonder what list has size 0 *)
      | setsize_h (n, []) = ...           (* extend list n times more *)
      | setsize_h (n, x::xs) = ...        (* not there yet *)
    
    fun delete_h (0, x::xs) = ...         (* delete element at this position *)
      | delete_h (n, []) = ...            (* list was too short *)
      | delete_h (n, x::xs) = ...         (* not there yet *)
    
    fun execute_ops [] xs = ...           (* no more operations to execute *)
      | execute_ops (list_op::list_ops) xs =
        let val new_xs = (case list_op of
                              insert (pos, elem) => insert_h (pos, elem, xs)
                            | delete pos         => delete_h (pos, xs)
                            | setsize size       => setsize_h (size, xs))
        in execute_ops list_ops new_xs
        end
    

    您可能希望使用execute_ops单独或组合测试这些功能:

    val test_insert_h_1 = insert_h (2, 7, [1,2,3,4]) = [1,2,7,4]
    val test_insert_h_2 = insert_h (9, 5, [1,2,3,4]) = [1,2,3,4,5]
    
    val test_setsize_h_1 = setsize_h (2, [5,6,7,8]) = [5,6]
    val test_setsize_h_2 = setsize_h (5, [1,2,3]) = [1,2,3,0,0]
    
    val test_delete_h_1 = delete_h (3, [4,5,6,7,8]) = [4,5,6,8]
    val test_delete_h_2 = delete_h (9, [1,2,3]) = [1,2,3]
    
    val test_execute_ops_1 =
        execute_ops [insert (0, 5), insert (1, 6), insert (2, 7)] [2,3,5] = [5,6,7]
    
    val test_execute_ops_2 =
        execute_ops [setsize 5, insert (4, 9)] [] = [0,0,0,0,9]
    
    val test_execute_ops_3 =
        execute_ops [setsize 6, insert (1, 5), delete 3] [8,8,8,8,9] = [8,5,8,9,0]