【发布时间】:2013-10-24 08:11:04
【问题描述】:
我想知道是否有办法获取一个数字列表(数字),并将这些数字截断成一个大数字(不是加法)。例如,我想要
(foo '(1 2 3 4))
;=> 1234
Scheme 有内置函数吗?
【问题讨论】:
-
不,但使用
reduce实现这一点相当容易
标签: math scheme integer-arithmetic
我想知道是否有办法获取一个数字列表(数字),并将这些数字截断成一个大数字(不是加法)。例如,我想要
(foo '(1 2 3 4))
;=> 1234
Scheme 有内置函数吗?
【问题讨论】:
reduce 实现这一点相当容易
标签: math scheme integer-arithmetic
Scheme 系列中有多种语言,Scheme 也有几个版本。如果您使用的是一个,例如,球拍,它包括一个左关联折叠(通常称为foldl、fold 或reduce,尽管也有其他变体),这很容易实现的折叠。这些问题和答案中更详细地描述了折叠:
fold 视为迭代构造的描述(并且在要求尾调用优化的Scheme 中,它被编译为迭代代码),还包括foldl 用于Scheme 的实现没有。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))))))
【讨论】:
fold-left 在 rnrs lists 库中
loop 更改为l->n 以避免任何混淆。