我一直试图解决这个问题几个小时。 函数展开,它获取元素和频率列表,并将它们扩展为一个简单的列表。例如,(展开'(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)))))
答案 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))))))