【问题标题】:Digits of a number in Racket are in random orderRacket中数字的数字是随机顺序的
【发布时间】:2015-06-25 11:47:23
【问题描述】:

我决定编写一个函数,给定一个数字将返回一个包含该数字中数字的列表,我的尝试是:

(define (rev-digits n)
  (if (= n 0)
    '()
    (cons (modulo n 10) (digits (quotient n 10)))))

(define (digits n)
  (reverse (rev-digits n)))

事实是,我需要按正确的顺序排列数字,但函数会返回,例如:

> (digits 1234567890)
'(9 7 5 3 1 2 4 6 8 0)

看似随机的顺序...您能帮我获得更协调的输出吗?

【问题讨论】:

  • 我无法重现此行为。该函数按预期工作并为我返回'(0 9 8 7 6 5 4 3 2 1)。我在 Windows 上使用 DrRacket 5.2.1。
  • @MarkusHimmel 我的错,代码不完整,让我添加更多上下文。

标签: recursion racket digit


【解决方案1】:

一个简单的解决方案:

#lang racket
(define (digits n)
  (for/list ([c (number->string n)])
    (- (char->integer c) (char->integer #\0))))

【讨论】:

    【解决方案2】:

    @JayKominek 给出的答案很准确,并修复了代码中的错误。为了补充它,这里有一个替代实现:

    (define (rev-digits n)
      (let loop ((n n) (acc '()))
        (if (< n 10)
            (cons n acc)
            (loop (quotient n 10) (cons (modulo n 10) acc)))))
    

    以上代码的优点是:

    • 它是尾递归的,因此效率更高
    • 它在n 为零时正确处理边缘情况(您的代码返回一个空列表)
    • 由于使用了名为let 的帮助程序,它不需要帮助程序
    • 它以正确的顺序构建列表,不需要在最后reverse

    【讨论】:

    • @Caridorc 检查这个替代实现
    【解决方案3】:

    rev-digits 需要调用自己,而不是digits

    (define (rev-digits n)
      (if (= n 0)
        '()
        (cons (modulo n 10) (rev-digits (quotient n 10)))))
    
    (define (digits n)
      (reverse (rev-digits n)))
    

    应该可以。

    值得注意的是,您的“随机”输出实际上并不是随机的;而是数字从列表的开头到结尾来回“弹跳”。这是有道理的,因为您实际上是在数字函数的“正常”版本和反转版本之间来回切换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多