Racket 中数字的数字是随机排列的

Digits of a number in Racket are in random order

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

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

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

事实是,我需要数字顺序正确,但是函数 returns,例如:

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

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

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)))

应该可以。

值得注意的是,您的 "random" 输出实际上并不是随机的;相反,数字从列表的开头到结尾来回 "bouncing"。这是有道理的,因为您有效地在数字函数的 "normal" 和反向版本之间来回切换。

@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 为零(您的代码 returns 是一个空列表)时,它可以正确处理边缘情况
  • 由于使用了命名 let
  • ,它不需要辅助程序
  • 它以正确的顺序构建列表,不需要 reverse 最后

一个简单的解决方案:

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