【问题标题】:SML : drop the first n elements of a listSML:删除列表的前 n 个元素
【发布时间】:2021-06-26 19:09:23
【问题描述】:

所以,我知道有一个内置函数可以删除元素,但如果您希望删除最后 n 个元素,它会起作用。 我想删除前 n 个元素。
一个例子:

  > drop([1,2,3,4], 2)   
    > [1,2]

我写了这段代码:

exception Subscription;

val counter = 0;

fun drop (l,0) = l 
| drop([], n) = raise Subscription
| drop(h::x, n) = if n<0 then raise Subscription
 else if(counter <n) then  
     let 
         val counter = counter +1
     in 
         (h:: drop(x,n))
     end    
 else nil
 ;    


drop([1,2,3,4],2);

它不会被编译。我得到的错误信息是:

   uncaught exception Subscription
    raised at: dropper.ml:6.23-6.35

任何想法和帮助表示赞赏。

【问题讨论】:

  • 回复:“我知道有一个内置函数可以删除元素,但如果你想删除最后 n 个元素,它可以工作。我想删除前 n 个元素”:我错过了一些东西.根据smlfamily.github.io/Basis/list.html#SIG:LIST.drop:VALList.drop 丢弃了第一个 i 元素,这正是你说的你想要的?
  • Re:“它不会被编译。我得到的错误信息是:uncaught exception Subscription”:这是矛盾的。如果您在代码运行时遇到未捕获的异常,则意味着您的代码确实 编译成功。 (您的代码在编译完成后才能运行。)
  • if counter &lt; n thenif 0 &lt; n then 相同。
  • 内置的 drop 确实会丢弃(即丢弃或删除)第一个元素。您要查找的内置函数是take
  • 你的最后一个子句本质上是drop (h::x,n) = h::drop(x,n)。 (您不需要外部计数器 - n 是您的计数器 - 而let 不是作业。您可能应该再次查看 SML 的基础知识。)

标签: sml smlnj


【解决方案1】:

您误解了val 声明的含义。它确实 不声明以后可以更改内容的变量 就像在命令式编程语言中一样。基本上:

  • 正如@kopec 所述,您的测试if(counter &lt; n) 毫无意义 因为它减少到if(0 &lt; n),因为counter被设置为0,即, 放在后面的val counter = counter + 1 对此没有影响 测试

  • 声明val counter = counter + 1 没有用。它 基本上意味着“现在 counters 设置为 counters + 1 (so 1) only in in ... end block following" 根本没有使用。

因此,您的代码相当于:

exception Subscription;

val counter = 0;

fun drop (l,0) = l 
| drop([], n) = raise Subscription
| drop(h::x, n) = if n<0 then raise Subscription
 else if(0 <n) then (h:: drop(x,n))
 else nil
 ;    

drop([1,2,3,4],2);

因此,很明显,通过您的示例列表,您将继续执行 递归调用 ((h:: drop(x,n))) 直到到达的第三个子句 引发异常的函数。

在这种情况下,解决问题的正确方法是 使用递归函数的参数:

exception Subscription;

fun drop(l, 0) = l 
|   drop([], n) = raise Subscription
|   drop(h :: x, n) =
   if n < 0 then raise Subscription
   else (h :: drop(x, n - 1)) 
 ;

drop([1,2,3,4],2);

因此,如果n 大于或等于输入列表的长度,您 最终会落在函数的第一个子句中。

(很高兴看到您熟悉模式匹配:))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 2014-04-02
    相关资源
    最近更新 更多