要列出的方案编号

时间:2012-10-11 07:41:00

标签: list scheme r5rs

我需要为我的程序编写一个子程序,该程序用一个整数表示,比如34109,然后将它放入一个包含元素3,4,1,0,9的列表中。整数可以是任意长度。有没有人有这个伎俩?我曾考虑过为每个地方使用模数,但我认为它不应该那么复杂。

3 个答案:

答案 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 1SRFI 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 - 样式)语法。