我需要为我的程序编写一个子程序,该程序用一个整数表示,比如34109,然后将它放入一个包含元素3,4,1,0,9的列表中。整数可以是任意长度。有没有人有这个伎俩?我曾考虑过为每个地方使用模数,但我认为它不应该那么复杂。
答案 0 :(得分:3)
我能想到的最简单的方法是使用算术运算和named let
来实现尾递归:
(define (number->list num)
(let loop ((num num)
(acc '()))
(if (< num 10)
(cons num acc)
(loop (quotient num 10)
(cons (remainder num 10) acc)))))
或者,您可以使用字符串操作解决此问题:
(define char-zero (char->integer #\0))
(define (char->digit c)
(- (char->integer c) char-zero))
(define (number->list num)
(map char->digit
(string->list (number->string num))))
这可以压缩成一个单独的函数,但我相信如果我们将子问题中的问题拆分成上面的话会更容易理解。
(define (number->list num)
(map (lambda (c) (- (char->integer c) (char->integer #\0)))
(string->list
(number->string num))))
无论如何,结果如预期:
(number->list 34109)
> '(3 4 1 0 9)
答案 1 :(得分:2)
这样的事情:
(define (num2list-helper num lst)
(cond ((< num 10) (cons num lst))
(else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))
(define (num2list num)
(num2list-helper num '()))
(num2list 1432)
正如itsbruce所评论的那样,你可以在主要函数中隐藏辅助函数:
(define (num2list num)
(define (num2list-helper num lst)
(cond ((< num 10) (cons num lst))
(else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))
(num2list-helper num '()))
(num2list 1432)
继续......
答案 2 :(得分:0)
我不喜欢手动循环,所以这里是基于展开的解决方案(首先加载SRFI 1和SRFI 26):
(define (digits n)
(unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))
但是返回0的空列表。如果您希望它返回(0)
,我们会添加一个特例:
(define (digits n)
(case n
((0) '(0))
(else (unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))))
当然,您可以将此概括为其他基础。在这里,我使用可选参数实现它,所以如果你没有指定基数,它默认为10:
(define (digits n (base 10))
(case n
((0) '(0))
(else (unfold-right zero? (cut modulo <> base) (cut quotient <> base) n))))
不同的Scheme实现对可选参数使用不同的语法;以上使用了Racket风格(和/或SRFI 89 - 样式)语法。