【问题标题】:Racket print length of "n" elements in a list列表中“n”个元素的球拍打印长度
【发布时间】:2015-09-26 23:30:25
【问题描述】:

我需要一些帮助来理解尾递归

    #lang racket

   (define (lista x)
   (printf(length(cons x (lista (read)))))
   )

   (lista (read))

我不知道如何结束链表的循环然后获取长度并打印这个数字。

例如,如果我输入了

  2
  1
  3
  5
  7
  5
  10

它必须打印7,但是编译器总是提示超时,所以我不知道我是否正确读取输入或有其他方法?

【问题讨论】:

  • 既然你在使用球拍,你应该使用 DrRacket。除了提供集成环境之外,它还会自动缩进您的代码,因此当您将其粘贴到 SO 中时,将其全部选中,然后点击 Ctrl-k 使其成为代码块,您的代码将是可读的.

标签: functional-programming racket


【解决方案1】:

你在做什么没有意义(我将在下面解释原因)。 如果您使用length,您可以立即返回列表的长度。你有一个无限循环的原因是因为你没有停止条件(即当列表为null? 时结束递归)。

我想这是一项需要您手动完成的作业,因此不使用length

(define (lngth lst)
  (if (null? lst) ; Did we checked the whole list already?
      0           ; This will put an end to the recursion !
      (+ 1        ; Tail recursive call, we add 1 because we call ourselve recusrively with the cdr of the list (hence with a list that is one shorter)
         (lngth (cdr lst)))))

现在你可以调用这个过程,(lngth '(1 2 3 4 5)) 将返回 5。


(define (lista x)
  (printf
   (length
    (cons x 
          (lista (read))))))

您的尝试存在一些问题。最大的问题是它缺少一个停止条件,这就是死循环的原因(它一次又一次地提示用户输入)。现在当你调用lista 时,你总是会一次又一次地遇到对自身的递归调用,因为(define (lista x) ... (cons x (lista ...)))

正如我上面所说,其余的代码并没有真正的意义。 您正在使用cons 而不是cdr 来遍历列表,并且您正在使用length 而不是为列表的当前元素添加一个(+ 1 (recursive call))

【讨论】:

  • 感谢详细的解释!我真的很感激!,我只用了几天球拍,所以很困惑,最后一个问题,一本书推荐?我老师的笔记很糟糕
  • @Tacocola Google SICP(计算机程序的结构和解释),它是类 Scheme 课程的经典。然而,它比(仅)学习该语言更深入,它还提出了 Scheme 语言的元循环实现,即实现一个 Scheme 评估器,用... Scheme 编写:)
  • @TacoCola,我不知道它是否还在,但有一本或曾经有一本名为如何设计程序的书,对Scheme 进行了温和的介绍。有或曾经支持它的球拍模式。
【解决方案2】:

你在递归中没有停止条件,这就是为什么它在不打印长度的情况下继续。例如,您可以通过查找某个输入来中断,例如“长度”以打印长度。

#lang racket

(define (get-length-of-input)
  (display "Enter a number or get the length (length for length)")
  (let input-loop ((result '()))
    (define input (read-line))
    (cond [(number? (string->number input)) 
           (input-loop (cons input result))]
          [(string=? input "length") 
           (displayln (length result))]
          [else (displayln "unknown input") 
                (input-loop result)])))

; Start the procedure
(get-length-of-input)

为了使其尾递归,迭代循环与named-let 一起使用。 named-let 使用初始值(空列表'())初始化循环并自动启动它。

然后进行案例分析(输入是数字、字符串“长度”还是其他?)。如果它是一个数字(通过尝试将输入字符串转换为数字来检查),则将此数字添加到局部变量result 并继续循环。如果输入是“长度”,则打印长度并且程序停止。否则显示“未知输入”并继续循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 2010-10-27
    • 2023-03-19
    • 2018-03-04
    • 2014-07-09
    • 1970-01-01
    相关资源
    最近更新 更多