方案扩展功能

时间:2011-04-09 02:31:28

标签: recursion scheme

我一直试图解决这个问题几个小时。 函数展开,它获取元素和频率列表,并将它们扩展为一个简单的列表。例如,(展开'(a(3b)(3a)b(2c)(3a))的结果应为(a b b b a a b c c a a a)

这是我的解决方案:


辅助功能:

(define (expandHelper n value)
  (if (= 0 n) 
      '()
      (cons (append (cons value '()))(expandHelper (- n 1) value)))) 

扩展功能

(define (expand lst) 
  (cond ((null? lst) '())
    (else (expandHelper (car lst) (cadr lst)))))

但是,它并没有达到我的预期。当列表只有一个元素值时,它会查找整数。例如,(展开'(a(2 b))。由于只有一个副本,它在表达式中没有(1 a)。我是Scheme的新手。如果你能的话我真的很感激帮助我。

由于

这是一个更新版本:但它仍然不对。如果有人帮我修改我的代码以获得正确的结果,我将非常感激。

;; helper function
(define (expandHelper value)
  (if (= 0 value) 
      '()
      (cons (append (cons (car sublist) '()))(expandHelper (- (car sublist) 1) (car sublist)))))  

;; the expand function
(define (expand lst) 
  (cond ((null? lst) '())
        (else (list? (car lst)) (expandHelper (car lst)) (expand (cadr lst)))))

5 个答案:

答案 0 :(得分:1)

这将是我的解决方案,没有任何辅助函数,并且在子列表上递归(即(3 a)变为(cons a(expand'(2 a))):

#lang racket

(define (expand lst)
  (cond
    ((null? lst) '())
    ((list? (car lst))
     (let ((cnt (caar lst)) (chr (cadar lst)))
       (if (= cnt 0)
           (expand (cdr lst))
           (cons chr (expand (cons (list (- cnt 1) chr) (cdr lst)))))))
    (else (cons (car lst) (expand (cdr lst))))))

答案 1 :(得分:1)

您可以将其表示为右侧折叠,并避免开发自定义递归函数。如果下一个元素是(3 a)之类的列表,请展开并添加前缀。如果是符号,只需cons

(define (expand xs)
  (fold-right
   (lambda (x result)
     (if (list? x)
     (append (apply make-list x) result)
         (cons x result)))
   '()
   xs))

答案 2 :(得分:0)

你应该在这里考虑两件事。第一个是你提到的那个 - 你可以有a(1 a),这两个意思都是一样的。您可能希望将其移至expandHelper,因此它看起来更像(expandHelper value),然后您应该切换它是列表还是符号。

第二个是你如何打电话expandHelper。如果您输入'(a (3 b) (3 a) b (2 c) (3 a))expand这样的列表,它目前会调用(expandHelper a (3 b)),这可能与您的想法不同。相反,您要确保在列表的每个元素上调用expandHelper,并将cons调用结果。您可以通过在列表的第一个元素上调用expandHelper,然后在列表的其余部分递归调用expand来完成此操作。

我没有检查过这个编译,这只是一般的想法:

(define (expandHelper value)
    (if (list? value) ;; means value is something like (2 a)

        (if (= 0 (car value)) ;; then (car value) is 2
            '() ;; if it's zero, we complete the list and return!
            (cons (cadr value) ;;otherwise, we append (cadr value) = a to...
                  (expandHelper (cons (- (car value) 1) (cadr value))))))
                  ;; the result of expand helper on (- (car value) 1) = 1 
                  ;; and (cadr value) = a

         (cons value '()))) ;; if it's not a list, we should just return the value.

答案 3 :(得分:0)

(define (term-expander n val partial)
  (if (zero? n)
    partial
    (term-expander (- n 1) val (cons val partial))))

(define (append-expand a b)
  (if (pair? b)
    (append a (term-expander (car b) (cadr b) '()))
    (append a (list b))))

(define (expand l) (foldl append-expand l '() ))

> (expand '(a (3 b) (3 a) b (2 c) (3 a)))
(a b b b a a a b c c a a a)

所以...... term-expander需要(5 a) - > '(a a a a a)'append-expand会将最新字词(如果它是一对,则展开)附加到我们正在进行的答案中。只需要将其折叠在列表上。

我希望你已经有了foldl,但是以下是以下情况。

(define (foldl op seq init)
  (define (iter acc rest)
    (if (null? rest)
      acc
      (iter (op acc (car rest)) (cdr rest))))
  (iter init seq))

修改

之后实现这可以通过foldr更自然地完成,而不是foldl(需要append-expand以不同方式编写)。你为什么不知道你是否能找到它?主要是相同的想法,但它将从后到前在列表上运行,并且更自然地适用于cons结构


这是我在没有折叠的情况下做的,但它的工作方式相同,我真的不关心它

(define (term-expander p partial)
  (if (zero? (car p))
    partial
    (term-expander (cons (- (car p) 1) (cdr p)) (cons (cadr p) partial))))

(define (expand l)
  (define (expand-rec l partial)
    (if (null? l)
      partial
      (let ((t 
        (if (pair? (car l))
             (term-expander (car l) '())
             (list (car l)))))
      (expand-rec (cdr l) (append partial t)))))
  (expand-rec l '()))

> (expand '(a (3 b) (3 a) b (2 c) (3 a)))
(a b bb a a a b c c a a a)

如果您愿意,(if (pair?...部分可以转到term-expander,然后您就可以全面调用它。我稍微喜欢这种方式,但它完全相同

答案 4 :(得分:0)

 (define (expand l)
   (cond ((null? l) '())
         ((not (pair? (car l))) (cons (car a) (expand (cdr l)))
         ((< (caar l) 1) (expand (cdr l)))
         (else (cons (cadar l)) (expand (cons (cons (- (caar l) 1) (cdar l))
                                                (cdr l))))))