入力 1:
(decompose '(* 1 2 3 4))
出力 1:
'(* 1 (* 2 (* 3 4)))
入力2
(decompose '(+ 1 2 3 (* 5 6 7)))
出力2
'(+ 1 (+ 2 (+ 3 (* 5 (* 6 7)))))
誰かがこれについてアイデアを持っていますか?
入力 1:
(decompose '(* 1 2 3 4))
出力 1:
'(* 1 (* 2 (* 3 4)))
入力2
(decompose '(+ 1 2 3 (* 5 6 7)))
出力2
'(+ 1 (+ 2 (+ 3 (* 5 (* 6 7)))))
誰かがこれについてアイデアを持っていますか?
評価と同じ方法ですが、結果を出力する代わりに、使用される式を出力するだけです。
ラケットでテストされた私の実装は次のとおりです。
(define (decompose expr)
(define (expand x)
(if (list? x)
(decompose x)
x))
(define oper (car expr))
(let next ((args (map expand (cdr expr))))
(if (<= (length args) 2)
(cons oper args)
(list oper (car args) (next (cdr args))))))
あなたがあなた自身の解決策を投稿したのを見るので、私の完全な答えを示しても大丈夫だと思います。相互再帰的なプロシージャのペアとして、別の可能な実装を次に示します。このソリューションではlength
orを使用する必要がなくlist?
(リストを不必要にトラバースする必要がある場合があります)、初等関数のみを使用するという事実が気に入っています( foldr
、、、またはその他の高階関数は必要ありません)。reverse
map
(define (decompose lst)
(if (or (null? lst) ; if the list is empty
(null? (cdr lst)) ; or has only one element
(null? (cddr lst))) ; or has only two elements
lst ; then just return the list
(process (car lst) ; else process car of list (operator)
(cdr lst)))) ; together with cdr of list (operands)
(define (process op lst)
(cond ((null? (cdr lst)) ; if there's only one element left
(if (not (pair? (car lst))) ; if the element is not a list
(car lst) ; then return that element
(decompose (car lst)))) ; else decompose that element
((not (pair? (car lst))) ; if current element is not a list
(list op ; build a list with operator,
(car lst) ; current element,
(process op (cdr lst)))) ; process rest of list
(else ; else current element is a list
(list op ; build a list with operator,
(decompose (car lst)) ; decompose current element,
(process op (cdr lst)))))) ; process rest of list
それはあなたの例、そしていくつかのために働きます:
(decompose '(* 1 2 3 4))
=> '(* 1 (* 2 (* 3 4)))
(decompose '(+ 1 2 3 (* 5 6 7)))
=> '(+ 1 (+ 2 (+ 3 (* 5 (* 6 7)))))
(decompose '(+ 1 (* 4 5 6) 2 3))
=> '(+ 1 (+ (* 4 (* 5 6)) (+ 2 3)))
(decompose '(+ 1 2 3 (* 5 6 7) 8))
=> '(+ 1 (+ 2 (+ 3 (+ (* 5 (* 6 7)) 8))))
(decompose '(+ 1 2 3 (* 5 6 7) (* 8 9 10) (* 11 12 (- 1))))
=> '(+ 1 (+ 2 (+ 3 (+ (* 5 (* 6 7)) (+ (* 8 (* 9 10)) (* 11 (* 12 (- 1))))))))
Chris Jester-Young
のソリューションから変更:
(define (decompose x)
(if (pair? x)
(let ((operator (car x))
(expanded-x (map decompose x)))
(let decompose-helper ((operands (cdr expanded-x)))
(if (<= (length operands) 2)
(cons operator operands)
(list operator (car operands) (decompose-helper (cdr operands))))))
x))