2013-09-29 125 views
3

这是一个我坚持的作业问题。我必须在不使用显式递归或本地的情况下在Racket中创建一个函数,该函数需要一个对的列表,其中每对的第一个元素是一个非负整数,并生成一个新的列表列表,其中每个列表都是k每对中第二个元素的出现次数,其中k是每对中的第一个元素。例如(expand-pairs(list(list 1 2)(list 3 4)))会产生(list(list 2)(list 4 4 4))创建重复元素清单列表

我得到了一些代码工作,但只有第二元素是一个数字。由于该问题没有说明第二个元素是什么类型的元素,我认为它需要适用于任何元素。所以我的函数可以解决上面的例子,但不能解决(扩展对(列表(列表1'a)(列表3'b)))。

这里是我的代码:

(define (expand-pairs plst) 
    (map 
    (lambda (x) 
    (map 
     (lambda (y) (+ (first (rest x)) y)) 
     (build-list (first x) (lambda (z) (- z z))))) 
    plst)) 

我的主要问题是我不知道如何不使用递归或建立列表创建长度为k的名单,但之后如果我用建名单中删除创建一个数字列表,我不知道如何将其转换为符号列表或任何其他元素。

任何人都可以指向正确的方向吗?

+0

这是一种形式的[游程长度编码(https://en.wikipedia.org/wiki/Run-length_encoding )。除了你在这里收到的答案外,你可以在[Rosetta Code for Run-length编码中的代码示例](http://rosettacode.org/wiki/Run-length_encoding)启示(并且存在用于各种Lisps(Clojure ,Common Lisp和Scheme))。这里的任务是压缩和解压_strings_(而不是列表清单),但是其中一些技术可能仍然有帮助。 –

+0

另外,关于术语“对”的说明。在Scheme中,_pair_通常意味着'cons'的返回值,即一个虚线对,一个cons-cell。因为'(1 2)==(1。(2。()))',这与两个元素的列表不同,实际上它们需要两个cons单元。我只是指出了这一点,因为基于规范说明函数“取对子列表”,这使得用例'(expand-pairs(list(list 1 2)(list 3 4)))'有点令人惊讶。它可能是'(expand-pairs(list(cons 1 2)(cons 3 4)))==(expand-pairs'((1。2)(3。4)))''。 –

回答

1

事情是这样的:

(define (expand-pairs plst) 
    (map (lambda(x) (build-list (car x) (lambda(k) (cadr x)))) plst)) 

您不必在build-list使用k,只需要对第二个元素。

3

这里的另一种可能的实现,建立在@ RomanPekar的答案,但对于拍多一点地道:

(define (expand-pairs lst) 
    (map (lambda (s) 
     (build-list (first s) (const (second s)))) 
     lst)) 

它使用的高阶程序mapconstbuild-list没有使用明确创建实现递归或local。这里的关键是要理解下面的表达式将如何返回x5副本:

(build-list 5 (const 'x)) 
      ^^ ^
     #copies constant element 

=> '(x x x x x) 
+0

我并不是所有球拍专家,但看起来像使用'const'的确在这里比较Racket-ly,所以+1 –