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=]))))
我决定编写一个函数,给定一个数字将 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=]))))