将数字列表转换为数字

时间:2013-10-23 23:37:13

标签: math scheme integer-arithmetic

我想知道是否有办法取一个数字列表(数字),并将这些数字一起截断为Scheme中的一个大数字(不是加法)。例如,我想要

(foo '(1 2 3 4))
;=> 1234

Scheme是否有内置函数来执行此操作?

1 个答案:

答案 0 :(得分:3)

Scheme系列中有许多语言,并且还有一些Scheme版本。如果您使用的是一个,例如,Racket,其中包括左关联折叠(通常称为foldlfoldreduce,尽管还有其他变体),这是在折叠方面实施起来相当直接。在这些问题和答案中已经更详细地描述了折叠:

  • Finding maximum distance between two points in a list (scheme)这个问题包括对fold如何被视为迭代构造的描述(以及在Scheme中,它要求尾部调用优化,被编译为迭代代码),还包括一个实现对于没有它的方案,foldl
  • Flattening a List of Lists这个问题是关于一个有点不寻常的折叠,以及如何(或标准折叠)可以用来展平列表。
  • scheme structures and lists这个问题有一个示例,说明如何调整传递给折叠的函数以实现稍微不同的行为。 (我还包括一个自以为是(但是真的;),我保证你)关于Common Lisp reduce如何提供比某些Scheme库中提供的更方便的界面的评论。

这是代码在foldl

方面的样子
(define (list->num digits)
  (foldl (lambda (digit n)
           (+ (* 10 n) digit))
         0
         digits))
> (list->num '(1 2 3 4))
1234 

如果您的语言拥有它,foldl很容易编写(例如,my answer to the one of the questions above包含实现)并使用上述代码,或者您可以自己编写整个函数(使用相同的方法):

(define (list->num-helper digits number-so-far)
  (if (null? digits)
      number-so-far
      (list->num-helper (cdr digits)
                        (+ (* 10 number-so-far)
                           (car digits)))))

(define (list->num digits)
  (list->num-helper digits 0))

通过使用名为let

,您可以更简洁一些
(define (list->num digits)
  (let l->n ((digits digits)
             (number 0))
    (if (null? digits)
        number
        (l->n (cdr digits)
              (+ (* 10 number)
                 (car digits))))))