2013-10-23 112 views
1

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

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

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

+1

没有,但是这是一个相当容易的实现使用'reduce' –

回答

3

Scheme系列中有许多语言,并且Scheme也有几个版本。如果您使用的是包含左侧关联折叠的球拍(通常称为foldl,foldreduce,尽管还有其他变体),那么在折叠方面实施起来相当直接。褶子有更详细的这些问题和答案被描述:

  • Finding maximum distance between two points in a list (scheme)这个问题包括fold如何可以被看作是一个反复的构建体(和方案,其中准许尾调用优化的说明,被编译成迭代代码),并且还包括针对没有它的方案的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)))))) 
+0

如果我不使用循环在这里(我没有得到我的书中的那部分)我只是遍历我的函数,直到列表为空是正确的? –

+1

这里没有“使用循环”。我只是使用“命名的let”构造,而恰巧使用了名称循环。我也会显示使用辅助函数的版本。 –

+1

在R6RS中,你在'rnrs lists'库中有'fold-left' – Sylwester

相关问题